热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

P2590[ZJOI2008]树的统计(zkw线段树版的树链剖分)

传送门题目描述一棵树上有nn个节点,编号分别为11到nn,每个节点都有一个权值ww。我们将以下面的形式来要求你对这棵树完成一些操作:

传送门

题目描述
一棵树上有 nn 个节点,编号分别为 11 到 nn,每个节点都有一个权值 ww。

我们将以下面的形式来要求你对这棵树完成一些操作:

I. CHANGE u t : 把结点 uu 的权值改为 tt。

II. QMAX u v: 询问从点 uu 到点 vv 的路径上的节点的最大权值。

III. QSUM u v: 询问从点 uu 到点 vv 的路径上的节点的权值和。

注意:从点 uu 到点 vv 的路径上的节点包括 uu 和 vv 本身。

输入格式
输入文件的第一行为一个整数 nn,表示节点的个数。

接下来 n-1n−1 行,每行 22 个整数 aa 和 bb,表示节点 aa 和节点 bb 之间有一条边相连。

接下来一行 nn 个整数,第 ii 个整数 w_iw
i

表示节点 ii 的权值。

接下来 11 行,为一个整数 qq,表示操作的总数。

接下来 qq 行,每行一个操作,以 CHANGE u t 或者 QMAX u v 或者 QSUM u v 的形式给出。

输出格式
对于每个 QMAX 或者 QSUM 的操作,每行输出一个整数表示要求输出的结果。

输入输出样例
输入 #1复制
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
输出 #1复制
4
1
2
2
10
6
5
6
5
16
说明/提示
对于 100 %100% 的数据,保证 1\le n \le 3\times 10^41≤n≤3×10
4
,0\le q\le 2\times 10^50≤q≤2×10
5

中途操作中保证每个节点的权值 ww 在 -3\times 10^4−3×10
4
到 3\times 10^43×10
4
之间。

树链剖分模板题,用zkw线段树做的

#include
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
#define eps 1e-8
//#define mod 1e9+7
using namespace std;
//const int mod=1e9+7;
const int M=1e7+5;
const int N=1e6+5;//?????????? 4e8
struct node
{int ver,next;
}e[N];
int tot,head[N];
int num;
int a[N],w[N],dfn[N],son[N],sz[N];
int dep[N],fa[N],top[N];
int tree1[N],tree2[N];
int n,m;
void add(int x,int y)
{e[++tot].ver=y;e[tot].next=head[x];head[x]=tot;
}
void addedge(int x,int y)
{add(x,y),add(y,x);
}
void dfs1(int x,int pre)
{int maxn=-1;sz[x]=1,dep[x]=dep[pre]+1;fa[x]=pre;for(int i=head[x];i;i=e[i].next){int y=e[i].ver;if(y==pre) continue;dfs1(y,x);sz[x]+=sz[y];if(sz[y]>maxn){maxn=sz[y];son[x]=y;} }
}
void dfs2(int x,int pre)
{dfn[x]=++num;top[x]=pre;w[num]=a[x];if(!son[x]) return;dfs2(son[x],pre);for(int i=head[x];i;i=e[i].next){int y=e[i].ver;if(y==fa[x]||y==son[x]) continue;dfs2(y,y);}
}
void bulid()
{for(m&#61;1;m<&#61;n&#43;1;m<<&#61;1);for(int i&#61;m&#43;1;i<&#61;m&#43;n;i&#43;&#43;) tree1[i]&#61;tree2[i]&#61;w[i-m];for(int i&#61;m-1;i;i--) tree1[i]&#61;tree1[i<<1]&#43;tree1[i<<1|1],tree2[i]&#61;max(tree2[i<<1],tree2[i<<1|1]);
}
void change(int pos,int x)
{pos&#43;&#61;m;tree1[pos]&#61;tree2[pos]&#61;x;pos>>&#61;1;for(int i&#61;pos;i;i>>&#61;1) tree1[i]&#61;tree1[i<<1]&#43;tree1[i<<1|1],tree2[i]&#61;max(tree2[i<<1],tree2[i<<1|1]);
}
int ask(int f,int l,int r)
{int ans1&#61;0,ans2&#61;-1e9;for(l&#61;l&#43;m-1,r&#61;r&#43;m&#43;1;l^r^1;l>>&#61;1,r>>&#61;1){if(~l&1) ans1&#43;&#61;tree1[l^1],ans2&#61;max(ans2,tree2[l^1]);if(r&1) ans1&#43;&#61;tree1[r^1],ans2&#61;max(ans2,tree2[r^1]);}if(f) return ans1;return ans2;
}
int qus(int f,int x,int y)
{int ans1&#61;0,ans2&#61;-1e9;while(top[x]!&#61;top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);ans1&#43;&#61;ask(1,dfn[top[x]],dfn[x]);ans2&#61;max(ans2,ask(0,dfn[top[x]],dfn[x]));x&#61;fa[top[x]];}if(dep[x]>dep[y]) swap(x,y);ans1&#43;&#61;ask(1,dfn[x],dfn[y]);ans2&#61;max(ans2,ask(0,dfn[x],dfn[y]));if(f) return ans1;return ans2;
}
void solve()
{int T;cin>>n;for(int i&#61;1;i<n;i&#43;&#43;){int x,y;scanf("%lld%lld",&x,&y);addedge(x,y);}for(int i&#61;1;i<&#61;n;i&#43;&#43;) scanf("%lld",&a[i]);dfs1(1,1);dfs2(1,1);bulid();cin>>T;while(T--){string s;int x,y;cin>>s>>x>>y;if(s&#61;&#61;"CHANGE") change(dfn[x],y);else if(s&#61;&#61;"QMAX") printf("%lld\n",qus(0,x,y));else printf("%lld\n",qus(1,x,y));}
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);solve();
// puts("");return 0;
}


推荐阅读
  • 题目概述:Sereja 拥有一个由 n 个整数组成的数组 a1, a2, ..., an。他计划执行 m 项操作,这些操作包括更新数组中的特定元素、增加数组中所有元素的值,以及查询数组中的特定元素。 ... [详细]
  • 题目描述:Balala Power! 时间限制:4000/2000 MS (Java/Other) 内存限制:131072/131072 K (Java/Other)。题目背景及问题描述详见正文。 ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • Day4今天继续复习搞基础课,加油!树形DP每一个节点都分为选和不选两种状态,选为f[i,1],不选为f[i,0]&# ... [详细]
  • 本文介绍了一种使用链剖分(Link-Cut Tree, LCT)来维护动态树结构的方法,特别是如何通过 LCT 来高效地管理子树的信息,如子树大小等。 ... [详细]
  • 【MySQL】frm文件解析
    官网说明:http:dev.mysql.comdocinternalsenfrm-file-format.htmlfrm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • UVa 11683: 激光雕刻技术解析
    自1958年发明以来,激光技术已在众多领域得到广泛应用,包括电子设备、医疗手术工具、武器等。本文将探讨如何使用激光技术进行材料雕刻,并通过编程解决一个具体的激光雕刻问题。 ... [详细]
  • 在学习了Splay树的基本查找功能后,可能会觉得它与普通的二叉查找树没有太大的区别,仅仅是通过splay操作减少了时间开销。然而,Splay树之所以被誉为“序列之王”,主要在于其强大的区间操作能力。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 本文针对HDU 1042 N! 问题提供详细的解析和代码实现。题目要求计算给定整数N(0 ≤ N ≤ 10000)的阶乘N!。文章不仅提供了算法思路,还附上了C++语言的具体实现。 ... [详细]
  • 本文详细探讨了HihoCoder平台上的1398号问题——最大权闭合子图的求解方法。通过具体实例,深入分析了最大权闭合子图的概念及其算法实现。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
author-avatar
手机用户2502927203
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有