Codevs 2460 == BZOJ 1036 树的统计
2460 树的统计
2008年省队选拔赛浙江
一棵树上有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之间。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define maxn 300001 5 using namespace std; 6 int head[maxn],dep[maxn],fa[maxn],a[maxn]; 7 int pos[maxn],top[maxn],size[maxn],son[maxn]; 8 int tot,n,m,cnt,maxsize,x,y,num; 9 struct Edge{int next,to;}e[maxn<<1]; 10 struct Node{int l,r,max,sum;}tre[maxn<<2]; 11 int read(){ 12 int x=0,f=1;char c=getchar(); 13 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 14 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 15 return x*f; 16 } 17 int max(int a,int b){if(a>b)return a;else return b;} 18 void Add_Edge(int u,int v){ 19 e[++num].to=v;e[num].next=head[u];head[u]=num; 20 } 21 void DFS_First(int now,int pre,int deepth){ 22 dep[now] = deepth; fa[now] = pre; size[now] = 1; 23 for(int i=head[now];i;i=e[i].next){ 24 int v=e[i].to; 25 if(v!=pre){ 26 DFS_First(v,now,deepth+1); 27 size[now] += size[v]; 28 if(son[now]==-1||size[v]>size[son[now]]) 29 son[now]=v; 30 } 31 } 32 } 33 void Get_Pos(int u,int Top){ 34 int k=0;maxsize++; 35 pos[u]=maxsize;top[u]=Top; 36 if(!son[u])return; 37 Get_Pos(son[u],Top); 38 for(int i=head[u];i;i=e[i].next) 39 if(dep[e[i].to]>dep[u]&&e[i].to!=son[u]) 40 Get_Pos(e[i].to,e[i].to); 41 return; 42 } 43 void Build(int now,int l,int r){ 44 tre[now].l=l;tre[now].r=r; 45 if(l==r){ 46 tre[now].sum=tre[now].max=0;return ; 47 } 48 int mid=(l+r)>>1; 49 Build(now<<1,l,mid);Build(now<<1|1,mid+1,r); 50 tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum; 51 tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max); 52 53 } 54 void Insert(int now,int poss,int val){ 55 if(tre[now].l==tre[now].r){ 56 tre[now].sum=tre[now].max=val;return; 57 } 58 int mid=(tre[now].l+tre[now].r)/2; 59 if(poss<=mid)Insert(now<<1,poss,val); 60 else if(poss>mid)Insert(now<<1|1,poss,val); 61 tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum; 62 tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max); 63 } 64 int QueryMax(int now,int l,int r){ 65 if(l<=tre[now].l&&tre[now].r<=r)return tre[now].max; 66 int mid=(tre[now].l+tre[now].r)>>1,total=-1e9; 67 if(l<=mid)total=max(total,QueryMax(now<<1,l,r)); 68 if(r>mid)total=max(total,QueryMax(now<<1|1,l,r)); 69 return total; 70 } 71 int QuerySum(int now,int l,int r){ 72 if(l<=tre[now].l&&tre[now].r<=r)return tre[now].sum; 73 int mid=(tre[now].l+tre[now].r)>>1,total=0; 74 if(l<=mid)total+=QuerySum(now<<1,l,r); 75 if(r>mid)total+=QuerySum(now<<1|1,l,r); 76 return total; 77 } 78 int SolveMax(int u,int v){ 79 int ans=-1e9; 80 while(top[u]!=top[v]){ 81 if(dep[top[u]]<dep[top[v]])swap(u,v); 82 ans=max(ans,QueryMax(1,pos[top[u]],pos[u])); 83 u=fa[top[u]]; 84 } 85 if(pos[u]>pos[v]) swap(u,v); 86 ans=max(ans,QueryMax(1,pos[u],pos[v])); 87 return ans; 88 } 89 int SolveSum(int u,int v){ 90 int ans=0; 91 while(top[u]!=top[v]){ 92 if(dep[top[u]]<dep[top[v]])swap(u,v); 93 ans+=QuerySum(1,pos[top[u]],pos[u]); 94 u=fa[top[u]]; 95 } 96 if(pos[u]>pos[v])swap(u,v); 97 ans+=QuerySum(1,pos[u],pos[v]); 98 return ans; 99 } 100 int main(){ 101 n=read(); 102 for(int i=1;i<n;i++){ 103 x=read();y=read(); 104 Add_Edge(x,y);Add_Edge(y,x); 105 } 106 for(int i=1;i<=n;i++) a[i]=read(); 107 DFS_First(1,0,0); 108 Get_Pos(1,1); 109 Build(1,1,maxsize); 110 for(int i=1;i<=n;i++) 111 Insert(1,pos[i],a[i]); 112 m=read();char sp[25]; 113 while(m--){ 114 scanf("%s",sp);scanf("%d%d",&x,&y); 115 if(sp[0]=='C')a[x]=y,Insert(1,pos[x],y); 116 else{ 117 if(sp[1]=='M') printf("%d\n",SolveMax(x,y)); 118 else printf("%d\n",SolveSum(x,y)); 119 } 120 } 121 return 0; 122 }
转载于:https://www.cnblogs.com/suishiguang/p/6502339.html
Codevs 2460 == BZOJ 1036 树的统计相关推荐
- bzoj 1036 树的统计Count
题意:... 解法:树链剖分,对点进行重编号,这样的话线段树中点的信息就是树中点的信息...别的很常规... 1 #include<cstdio> 2 #include<cstrin ...
- 树链剖分入门+HYSBZ - 1036树的统计Count
今天学习了树链剖分,记录一下. [题目背景] HYSBZ - 1036树的统计Count [题目分析] 题目要求求任意结点之间路径的和以及路径上最大的结点,还有可能修改.如果正常做可能会很复杂(我也不 ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3427 Solved: 1429 [Submi ...
- 【BZOJ】【1036】树的统计
嗯这题是一道对树进行动态修改&查询的经典题目,可以拿来练习树链剖分~ 啊对于这种动态修改&查询的题目,我们最喜闻乐见的就是在一个序列上去做了,毕竟可以直接套各种数据结构模版啊,比如线段 ...
- 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)
树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...
- [ZJOI2008][BZOJ1036] 树的统计count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 7980 Solved: 3266 [Submi ...
- codevs 1729 单词查找树
二次联通门 : codevs 1729 单词查找树 /*codevs 1729 单词查找树Trie树统计节点个数建一棵Trie树插入单词时每新开一个节点就计数器加1*/ #include <cs ...
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- 洛谷 P2590 [ZJOI2008]树的统计
P2590 [ZJOI2008]树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把 ...
最新文章
- 长安大学微型计算机原理与接口技术答案,长安大学微机原理与接口技术A卷答案...
- python合并excel文件关键字_使用 Python 合并多个格式一致的 Excel 文件,Excel 表格...
- Ubuntu18.04安装cuDNN和Tensorflow的正确姿势
- linux电脑合盖后卡住了,解决ubuntu合盖后无法唤醒
- ES6/05/正则表达式简介,正则表达式如何使用,正则表达式中的特殊字符(边界符,量词符),预定义类,正则表达式中的替换
- Mathpix图片转LaTeX,Word快速插入LaTeX公式教程
- 操作系统文件管理_计算机民科笔记-操作系统week1
- gitlab版本控制系统源码部署
- 深度学习系列--1.入坑模型: 线性回归,logistic 回归,softmax分类器
- 一次library cache pin故障的解决过程
- 【算法笔记】图文结合彻底搞懂后缀数组
- STM32串口接收以及发送大全
- weblogic安装部署linux下
- html页面显示不全问题,网页显示不完全
- 矩阵和POJ 3233
- Dubbo之手写RPC框架
- 这五款小众软件你肯定不知道
- python算程序员吗_2019为什么有人说Python程序员是假的程序员?
- java输入值按回车下一个_java 如何 按回车 光标换到下个输入框
- Python小游戏--数字“炸弹“