P2590 [ZJOI2008]树的统计(LCT)
P2590 [ZJOI2008]树的统计
题目描述
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。
我们将以下面的形式来要求你对这棵树完成一些操作:
I. CHANGE u t : 把结点u的权值改为t
II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
III. QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
输入输出格式
输入格式:
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。
接下来一行n个整数,第i个整数wi表示节点i的权值。
接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
输出格式:
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
输入输出样例
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
4
1
2
2
10
6
5
6
5
16
说明
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
code
树链剖分1000ms左右,动态树4000ms多,不过动态树比树链剖分好写一点。
#include<cstdio>
#include<algorithm> using namespace std; const int N = ; int val[N],fa[N],ch[N][],rev[N],sum[N],mx[N],st[N],top;
struct Edge{
int to,nxt;
}e[N<<];
int head[N],tot; inline void add_edge(int u,int v) {
e[++tot].to = v,e[tot].nxt = head[u],head[u] = tot;
}
void pushup(int x) {
sum[x] = sum[ch[x][]] + sum[ch[x][]] + val[x];
mx[x] = max(max(mx[ch[x][]],mx[ch[x][]]),val[x]);
}
void pushdown(int x) {
int l = ch[x][],r = ch[x][];
if (rev[x]) {
rev[l] ^= ;rev[r] ^= ;
swap(ch[x][],ch[x][]);
rev[x] ^= ;
}
}
bool isroot(int x) {
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
int son(int x) {
return ch[fa[x]][]==x;
}
void rotate(int x) {
int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
if (!isroot(y)) ch[z][c] = x;fa[x] = z;
ch[x][!b] = y;fa[y] = x;
ch[y][b] = a;if (a) fa[a] = y;
pushup(y);pushup(x);
}
void splay(int x) {
top = ;st[++top] = x;
for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i];
while (top) pushdown(st[top--]);
while (!isroot(x)) {
int y = fa[x];
if (!isroot(y)) {
if (son(x)==son(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
}
void access(int x) {
for (int t=; x; t=x,x=fa[x]) {
splay(x);ch[x][] = t;pushup(x);
}
}
void makeroot(int x) {
access(x);
splay(x);
rev[x] ^= ;
}
void update(int x,int y) {
makeroot(x);val[x] = y;pushup(x);
}
int query_max(int x,int y) {
makeroot(x);access(y);splay(y);
return mx[y]; // -
}
int query_sum(int x,int y) {
makeroot(x);access(y);splay(y);
return sum[y]; // -
}
void dfs(int u) {
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==fa[u]) continue;
fa[v] = u;
dfs(v);
}
}
int main() {
int n,q,x,y;
char opt[];
mx[] = -1e9; // -
scanf("%d",&n);
for (int a,b,i=; i<n; ++i) {
scanf("%d%d",&a,&b);
add_edge(a,b);add_edge(b,a);
}
for (int i=; i<=n; ++i) scanf("%d",&val[i]);
dfs();
scanf("%d",&q);
while (q--) {
scanf("%s%d%d",opt,&x,&y);
if (opt[]=='H') update(x,y);
else if (opt[]=='M') printf("%d\n",query_max(x,y));
else printf("%d\n",query_sum(x,y));
}
return ;
}
P2590 [ZJOI2008]树的统计(LCT)的更多相关文章
- P2590 [ZJOI2008]树的统计(树链剖分)
P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- Luogu P2590 [ZJOI2008]树的统计
最近在学树剖,看到了这题就做了 [ZJOI2008]树的统计 思路 从题面可以知道,这题是树剖题(要求的和模板没什么区别呀喂 就是在普通的树剖上加了一个最大值 所以可以知道就是树剖+特殊的线段树 线段 ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- 【luogu P2590 [ZJOI2008]树的统计】 题解
题目链接:https://www.luogu.org/problemnew/show/P2590 我想学树剖QAQ #include <cstdio> #include <cstri ...
- 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树
题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...
- 洛谷 P2590 [ZJOI2008]树的统计(树链剖分)
题目描述一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- 洛谷 P2590 [ZJOI2008]树的统计
大家好,我非常喜欢暴力数据结构,于是我用块状树过了这道题目 题目: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE ...
- P2590 [ZJOI2008]树的统计
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
随机推荐
- h5新增属性本地存储
---恢复内容开始--- 存储的两种类型: localStorage 和 sessionStorage localstorage:没有时间限制的数据存储 sessionStorage 针对一个ses ...
- nc扫描端口
nc -n -v -z -w 1 ip地址 1-1000 (端口号) 详细信息 -v 排除dns -n 不发送任何数据-z 超时设置为1秒 -w 1
- SqlServer作业指定目标服务器
用SSMS生成数据库作业的创建脚本的时候,有一步是sp_add_jobserver操作: EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = ...
- 在github中的READEME中添加图片或者动图
在github中reademe中添加动图或者图片 将你需要展示的图片放在这个项目中的某个文件夹中,然后再reademe中这样引入 
A Cdgame brute force... B Drbalance 贪心,每次选最前面的-变成+,相当于后面所有的负值+2. C Treestrat 考虑集中去抓一个Red Token,以这个To ...
- POJ-2226 Muddy Fields---二分图匹配+巧妙构图
题目链接: https://vjudge.net/problem/POJ-2226 题目大意: 用宽度为1长度不限的木板将水洼‘*’盖住而不盖住草‘.' Sample Input 4 4 *.*. . ...
- NFS服务器实现文件共享
NFS服务器运行原理 实战配置NFS服务器 配置Samba服务器及实现文件共享 (一)NFS器服务端描述 NFS服务器: Network File System,网络文件系统使FreeBSD支持的一种 ...
- python_52_函数返回值2
def test1(x,y): print(x,y) test1(1,2)#位置参数调用,按顺序来,与形参一一对应 test1(y=1,x=2)#输出为2 1,不是1 2.关键字参数调用按关键字,不按 ...
- C# 目录下的文件操作
运用DirectoryInfo类的对象我们可以轻松的实现对目录以及和目录中的文件相关的操作,假如你要获得某个目录F:\Pictures下的所有BMP文件,那么通过下面的代码就可以实现该功能. 上面的代 ...