BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)
来源:互联网 发布:数控编程的步骤是什么 编辑:程序博客网 时间:2024/06/06 04:28
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8421 Solved: 3439
[Submit][Status][Discuss]
Description
一棵树上有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本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
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 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
Sample Output
4
1
2
2
10
6
5
6
5
16
1
2
2
10
6
5
6
5
16
HINT
Source
树的分治
ac代码
/************************************************************** Problem: 1036 User: kxh1995 Language: C++ Result: Accepted Time:3540 ms Memory:13000 kb****************************************************************/ #include<stdio.h> #include<string.h> #include<queue>#include<iostream>#define INF 0x7fffffff#define max(a,b) (a>b?a:b)using namespace std;int vis[200050]; struct LCT { int bef[200050],pre[200050],next[200050][2],sum[200050],key[200050],val[200050]; void init() { memset(pre,0,sizeof(pre)); memset(next,0,sizeof(next)); val[0]=-INF; sum[0]=0; } void pushup(int x) { sum[x]=key[x]+sum[next[x][1]]+sum[next[x][0]]; val[x]=max(key[x],max(val[next[x][1]],val[next[x][0]])); } void rotate(int x,int kind) { int y,z; y=pre[x]; z=pre[y]; next[y][!kind]=next[x][kind]; pre[next[x][kind]]=y; next[z][next[z][1]==y]=x; pre[x]=z; next[x][kind]=y; pre[y]=x; pushup(y); } void splay(int x) { int rt; for(rt=x;pre[rt];rt=pre[rt]); if(x!=rt) { bef[x]=bef[rt]; bef[rt]=0; while(pre[x]) { if(next[pre[x]][0]==x) { rotate(x,1); } else rotate(x,0); } pushup(x); } } void access(int x) { int fa; for(fa=0;x;x=bef[x]) { splay(x); pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=fa; pre[fa]=x; bef[fa]=0; fa=x; pushup(x); } } void change(int x,int y) { key[x]=y; splay(x); } int query(int x,int y,int flag) { access(y); for(y=0;x;x=bef[x]) { splay(x); if(!bef[x]) { if(flag) return max(key[x],max(val[next[x][1]],val[y])); else return key[x]+sum[next[x][1]]+sum[y]; } pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=y; pre[y]=x; bef[y]=0; y=x; pushup(x); } return 0; }}lct;struct s{ int u,v,next;}edge[200020<<1];int head[200020],cnt;void add(int u,int v){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++;}void bfs(int u) { int i,y; queue<int>q; memset(vis,0,sizeof(vis)); vis[u]=1; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { lct.bef[v]=u; vis[v]=1; q.push(v); } } } } int main(){ int n; while(scanf("%d",&n)!=EOF) { int i; memset(head,-1,sizeof(head)); cnt=1; lct.init(); for(i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(i=1;i<=n;i++) { int x; scanf("%d",&x); lct.key[i]=x; } bfs(1); int q; scanf("%d",&q); while(q--) { char str[10]; int x,y; scanf("%s%d%d",str,&x,&y); if(!strcmp(str,"QMAX")) { printf("%d\n",lct.query(x,y,1)); } else if(!strcmp(str,"QSUM")) { printf("%d\n",lct.query(x,y,0)); } else lct.change(x,y); } }}
0 0
- BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)
- bzoj1036: [ZJOI2008]树的统计Count [Link-Cut-Tree/树链剖分]
- bzoj1036 [ZJOI2008]树的统计Count (树链剖分|Link Cut Tree)
- 【ZJOI2008】【link-cut tree】树的统计
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- 【BZOJ 1036】[ZJOI2008]树的统计Count
- bzoj 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- bzoj 1036 [ZJOI2008]树的统计Count
- 【bzoj】1036: [ZJOI2008]树的统计Count
- [BZOJ]1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008] 树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- 【bzoj 1036】 [ZJOI2008]树的统计Count
- Unity Shader 学习笔记 (七) 根据切线和法线方向设置模型颜色shader
- 学好英语的18条黄金法则
- 数组和指针
- 算法题1:蛇形打印矩阵
- 盒模型
- BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)
- poj1088 滑雪
- window打开服务的dos命令
- TCP为什么要三次握手而不采用两次握手
- NS3网络仿真(13): FdNetDevice的问题
- IOS学习之OC面向对象—封装
- 整形数组合并
- C++ delete错误
- hdu-2680Choose the best route (dijkstra求最短路)