【bzoj 1036】树的统计(树链剖分)
来源:互联网 发布:亚投行 知乎 编辑:程序博客网 时间:2024/06/05 11:48
传送门biu~
#include<bits/stdc++.h>#define INF 2147483640#define max(x,y) (x>y?x:y)#define min(x,y) (x<y?x:y)using namespace std;int n;int dep[30005],v[30005],top[30005],tim;int siz[30005],son[30005],fa[30005],pos[30005];int head[30005],nex[60005],to[60005],tp;struct data{int L,R,sum,Max;}tree[30005<<2];inline void add(int x,int y){ nex[++tp]=head[x]; head[x]=tp; to[tp]=y;}void dfs1(int x,int father){ siz[x]=1; for(int i=head[x];i;i=nex[i]){ if(to[i]==father) continue; fa[to[i]]=x;dep[to[i]]=dep[x]+1; dfs1(to[i],x); siz[x]+=siz[to[i]]; if(siz[to[i]]>siz[son[x]]) son[x]=to[i]; }}void dfs2(int x,int tp){ top[x]=tp;pos[x]=++tim; if(!son[x]) return; dfs2(son[x],tp); for(int i=head[x];i;i=nex[i]){ if(to[i]==fa[x] || to[i]==son[x]) continue; dfs2(to[i],to[i]); }}void buildtree(int num,int L,int R){ tree[num].L=L; tree[num].R=R; if(L==R){ tree[num].Max=-INF; return; } int mid=L+R>>1; buildtree(num<<1,L,mid); buildtree(num<<1|1,mid+1,R);}void change(int num,int x,int y){ if(tree[num].L==tree[num].R){ tree[num].sum=tree[num].Max=y; return; } int mid=tree[num].L+tree[num].R>>1; if(x<=mid)change(num<<1,x,y); if(x>mid) change(num<<1|1,x,y); tree[num].sum=tree[num<<1].sum+tree[num<<1|1].sum; tree[num].Max=max(tree[num<<1].Max,tree[num<<1|1].Max);}int querysum(int num,int x,int y){ if(x<=tree[num].L && tree[num].R<=y) return tree[num].sum; int mid=tree[num].L+tree[num].R>>1; if(y<=mid) return querysum(num<<1,x,y); if(x>mid) return querysum(num<<1|1,x,y); return querysum(num<<1,x,y)+querysum(num<<1|1,x,y);}inline int searchsum(int x,int y){ int re=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); re+=querysum(1,pos[top[x]],pos[x]); x=fa[top[x]]; } if(pos[x]>pos[y]) swap(x,y); re+=querysum(1,pos[x],pos[y]); return re;}int querymax(int num,int x,int y){ if(x<=tree[num].L && tree[num].R<=y) return tree[num].Max; int mid=tree[num].L+tree[num].R>>1; if(y<=mid) return querymax(num<<1,x,y); if(x>mid) return querymax(num<<1|1,x,y); return max(querymax(num<<1,x,y),querymax(num<<1|1,x,y));}inline int searchmax(int x,int y){ int re=-INF; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); re=max(re,querymax(1,pos[top[x]],pos[x])); x=fa[top[x]]; } if(pos[x]>pos[y]) swap(x,y); re=max(re,querymax(1,pos[x],pos[y])); return re;}int main(){ scanf("%d",&n); for(int i=1;i<n;++i){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(int i=1;i<=n;++i) scanf("%d",&v[i]); dfs1(1,1);dfs2(1,1); buildtree(1,1,n); for(int i=1;i<=n;++i) change(1,pos[i],v[i]); int q; scanf("%d",&q); for(int i=1;i<=q;++i){ char opt[10]; int x,y; scanf("%s%d%d",opt,&x,&y); if(opt[0]=='C'){ v[x]=y; change(1,pos[x],y); } else if(opt[1]=='M') printf("%d\n",searchmax(x,y)); else printf("%d\n",searchsum(x,y)); } return 0;}
阅读全文
0 0
- 【bzoj 1036】树的统计(树链剖分)
- 【bzoj 1036】树的统计(树链剖分)
- BZOJ 1036 树的统计 Count 树链剖分
- BZOJ 1036 树的统计 树链剖分
- BZOJ 1036 树的统计Count 树链剖分
- BZOJ 1036 树的统计Count 树链剖分
- BZOJ 1036 树的统计Count(树链剖分+线段树)
- 【BZOJ 1036】树的统计Count(树链剖分)
- [BZOJ 1036][ZJOI2008]树的统计Count(树链剖分)
- 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)
- BZOJ 1036 树的统计(树链剖分模板题)
- Bzoj 1036 树的统计
- bzoj 1036 树的统计
- BZOJ 1036 树的统计
- BZOJ 1036 树的统计
- 【BZOJ】1036 [ZJOI2008]树的统计Count 树链剖分+线段树
- bzoj 1036 [ZJOI2008]树的统计Count 线段树+树链剖分
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
- Caffe学习笔记4--最优求解过程Solver
- node.js升级的问题
- AlphaGo Zero与增强学习
- MVP框架使用Fretiofit获取网络数据使用xrecycleview实现上拉加载下拉刷新
- es6学习第1天,箭头函数 块级作用域
- 【bzoj 1036】树的统计(树链剖分)
- selenium模块
- 引水入城
- HDU-1597 find the nth digit【二分法】
- 使用div的float样式时,div的parent 的height属性是0
- c#中的自定义属性
- 创建登录界面
- python基础系列教程——python所有包库的下载
- hdfs写入无权限解决方法