【CS 2460】树的统计(树链剖分)
来源:互联网 发布:wpsoffice是什么软件 编辑:程序博客网 时间:2024/06/08 15:37
很经典的树剖板子题目
题目传送门
结果点了这里直接去了题解空间
时间限制: 2 s
空间限制: 128000 KB
题目等级 : 大师 Master
题目描述 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 Description
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。
接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。
接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
输出描述 Output Description
对于每个“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
样例输出 Sample Output
4
1
2
2
10
6
5
6
5
16
数据范围及提示 Data Size & Hint
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
解题思路:
题解真的是贼长啊。。。。。。可以去看一下上一篇发的【树链剖分笔记详解】,在那里有比较详细的解释【跑】
这里直接附上代码:
#include<iostream>#include<cstdio>#include<cstring>#define ls p<<1#define rs p<<1|1#define mid (shu[p].l+shu[p].r >>1)#define RI register intusing namespace std;const int sz = 300010;int pos[sz],son[sz],top[sz],size[sz];int dep[sz],fa[sz],fir[sz],nxt[sz];int w[sz];int tot,n,q,cnt,x,y,num;char ch[15];struct node{ int l,r; int sum,max;}shu[sz<<2];struct ed{ int f,t;}l[sz<<1];inline void read(int &x){ x = 0;bool flag = 0; char ch = getchar(); while(ch < '0' || ch > '9') {if(ch == '-') flag = 1;ch = getchar();} while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();} if(flag) x *= -1;}inline void add(int f,int t){ l[++tot]=(ed){f,t}; nxt[tot]=fir[f]; fir[f]=tot;}inline void build(int p,int l,int r){ shu[p].l=l,shu[p].r=r; if(l==r) { shu[p].sum = shu[p].max=0; return; } int midd = l+r>>1; build(ls,l,midd); build(rs,midd+1,r); shu[p].sum=shu[ls].sum+shu[rs].sum; shu[p].max=max(shu[ls].max,shu[rs].max); }void dfs1(int k,int f,int d){ dep[k]=d; fa[k]=f; size[k]=1; for(RI i=fir[k];i;i=nxt[i]) { int x=l[i].t; if(x==f) continue; dfs1(x,k,d+1); size[k]+=size[x]; if(!son[k]||size[x]>size[son[k]]) son[k]=x; }}void dfs2(int k,int tot){ top[k]=tot; pos[k]=++num; if(!son[k]) return; dfs2(son[k],tot); for(RI i=fir[k];i;i=nxt[i]) { int x=l[i].t; if(x!=son[k]&&x!=fa[k]) dfs2(x,x); }}void in(int p,int x,int v){ if(shu[p].l==shu[p].r) { shu[p].sum=shu[p].max=v; return; } if(x<=mid) in(ls,x,v); else if(x>mid) in(rs,x,v); shu[p].sum=shu[ls].sum+shu[rs].sum; shu[p].max=max(shu[ls].max,shu[rs].max);}int qsum(int p,int l,int r){ if(shu[p].l>=l&&shu[p].r<=r) return shu[p].sum; int ans=0; if(l<=mid) ans+=qsum(ls,l,r); if(r>mid) ans+=qsum(rs,l,r); return ans;}int qmax(int p,int l,int r){ if(shu[p].l>=l&&shu[p].r<=r) return shu[p].max; int ans=-10000007; if(l<=mid) ans=max(ans,qmax(ls,l,r)); if(r>mid) ans=max(ans,qmax(rs,l,r)); return ans;}int dosum(int x,int y){ int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=qsum(1,pos[top[x]],pos[x]); x=fa[top[x]]; } if(pos[x]>pos[y]) swap(x,y); ans+=qsum(1,pos[x],pos[y]); return ans; }int domax(int x,int y){ int ans=-1e8; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,qmax(1,pos[top[x]],pos[x])); x=fa[top[x]]; } if(pos[x]>pos[y]) swap(x,y); ans=max(ans,qmax(1,pos[x],pos[y])); return ans;}int main(){ read(n); for(RI i=1;i<n;i++) { read(x),read(y); add(x,y); add(y,x); } for(RI i=1;i<=n;i++) read(w[i]); dfs1(1,0,1); dfs2(1,1); build(1,1,n); for(RI i = 1;i <= n;i ++) in(1,pos[i],w[i]); read(q); while(q--) { scanf("%s",ch); read(x),read(y); if(ch[0]=='C') { w[x]=y; in(1,pos[x],y); } else { if(ch[1]=='M') printf("%d\n",domax(x,y)); else printf("%d\n",dosum(x,y)); } } return 0; }
- 【CS 2460】树的统计(树链剖分)
- Codevs 2460 树的统计 [树链剖分]
- 【ZJOI2008】树的统计(树链剖分)
- bzoj1036 [ZJOI2008]树的统计(树链剖分)
- 【bzoj 1036】树的统计(树链剖分)
- 【bzoj 1036】树的统计(树链剖分)
- SqlHelper.cs 通过IP地址统计网站的访问量常用的微软工具
- bzoj1036 树的统计 树链剖分
- ZJOI2008 树的统计 树链剖分
- 对CS的理解(不断更新)
- 汇编寄存器(cs,ds)的区别
- 【CS】(奇妙的)虚拟存储器
- bzoj 1036 Codevs 2460 树的统计 [树链剖分]
- 驳斥: Lotus Notes/Domino CS有读者域控制情况下如何进行所有文档的分类统计
- BZOJ 1036 树的统计Count(树链剖分+线段树)
- HYSBZ 1036 树的统计Count (树链剖分 + 线段树)
- ZJOI 2008 树的统计(树链剖分+线段树)
- HYSBZ 1036 树的统计Count(树链剖分+线段树)
- httpd服务如何开机自启
- Linux 排错 误删 /etc/fstab 和 /boot怎样恢复
- Linux 启动流程
- java安装和环境变量
- 跨域问题
- 【CS 2460】树的统计(树链剖分)
- file结构体
- 浏览器的解析渲染过程
- 从地址栏输入网址时,敲下回车后,发生哪些了哪些事情?
- house of orange
- 把 Script 标签 放在页面的最底部的 body 封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?
- 序列化二叉树
- Oracle 树操作(select…start with…connect by…prior)
- 新消费时代下,中国咖啡市场将如何发展?