bzoj3531 [Sdoi2014]旅行 树链剖分 线段树
2016-11-22 20:34
351 查看
先树剖,然后对于每个值开一个动态开点的线段树。
#include <bits/stdc++.h> using namespace std; #define N 110000 #define M 11000000 #define ls l,mid,ch[now][0] #define rs mid+1,r,ch[now][1] int n,q,tot,cnt; int w ,c ,head ,nex[N<<1],to[N<<1]; int fa ,deep ,son ,size ,pos ,bel ,top ; int root ,ch[M][2],mx[M],sum[M]; char s[11]; struct node { int sum,mx; node(){} node(int sum,int mx):sum(sum),mx(mx){} friend node operator + (const node &r1,const node &r2) {return node(r1.sum+r2.sum,max(r1.mx,r2.mx));} }; void add(int x,int y) { tot++; nex[tot]=head[x];head[x]=tot; to[tot]=y; } void dfs(int x,int y) { fa[x]=y;size[x]=1; deep[x]=deep[y]+1; for(int i=head[x];i;i=nex[i]) if(to[i]!=y) { dfs(to[i],x);size[x]+=size[to[i]]; son[x]=size[to[i]]>size[son[x]] ? to[i]:son[x]; } } void dfs1(int x,int y,int tp) { pos[x]=++cnt;bel[cnt]=x; top[x]=tp; if(son[x])dfs1(son[x],x,tp); for(int i=head[x];i;i=nex[i]) if(to[i]!=y&&to[i]!=son[x]) dfs1(to[i],x,to[i]); } void insert(int l,int r,int &now,int pos,int v,int tp) { if(!now)now=++cnt; sum[now]+=v*tp; if(l==r){mx[now]+=v*tp;return;} int mid=(l+r)>>1; if(mid>=pos)insert(ls,pos,v,tp); else insert(rs,pos,v,tp); mx[now]=max(mx[ch[now][0]],mx[ch[now][1]]); } node query(int l,int r,int now,int lq,int rq) { if(lq<=l&&r<=rq) return node(sum[now],mx[now]); int mid=(l+r)>>1; node ret(0,0); if(mid>=lq)ret=ret+query(ls,lq,rq); if(mid<rq) ret=ret+query(rs,lq,rq); return ret; } node query(int x,int y,int c) { node ret(0,0); while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]])swap(x,y); ret=ret+query(1,n,root[c],pos[top[x]],pos[x]); x=fa[top[x]]; } if(deep[x]<deep[y])swap(x,y); ret=ret+query(1,n,root[c],pos[y],pos[x]); return ret; } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]); for(int i=1,x,y;i<n;i++) { scanf("%d%d",&x,&y); add(x,y);add(y,x); } dfs(1,0); dfs1(1,0,1);cnt=0; for(int i=1;i<=n;i++) insert(1,n,root[c[i]],pos[i],w[i],1); for(int x,y;q--;) { scanf("%s%d%d",s,&x,&y); if(s[0]=='C') { insert(1,n,root[c[x]],pos[x],w[x],-1); if(s[1]=='C')insert(1,n,root[y],pos[x],w[x],1),c[x]=y; else insert(1,n,root[c[x]],pos[x],y,1),w[x]=y; } else { node ans=query(x,y,c[x]); if(s[1]=='S')printf("%d\n",ans.sum); else printf("%d\n",ans.mx); } } return 0; }
相关文章推荐
- [Sdoi 2014] bzoj3531 旅行 [树链剖分]
- 【BZOJ3531】旅行(SDOI2014)-树链剖分+动态加点线段树
- |BZOJ 3531|树链剖分|动态开点线段树|[Sdoi2014]旅行
- [树链剖分 线段树] BZOJ 3531 [Sdoi2014]旅行
- 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
- Bzoj3531:[Sdoi2014]旅行:树链剖分+动态开点线段树
- BZOJ 3531 [Sdoi2014]旅行 树链剖分 线段树
- bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)
- bzoj3531 [Sdoi2014]旅行(树链剖分+动态开点线段树)
- BZOJ3531 [Sdoi2014]旅行——树剖+动态开点线段树
- BZOJ3531 [Sdoi2014]旅行 【树剖 + 线段树】
- bzoj3531 [Sdoi2014]旅行 树链剖分+动态开线段树
- 【BZOJ】【P3531】【SDOI2014】【旅行】【题解】【树链剖分】
- BZOJ 3531 SDOI2014 旅行 树链剖分
- 【bzoj3531】[Sdoi2014]旅行 动态开点的线段树
- bzoj3531: [Sdoi2014]旅行
- BZOJ3531 [Sdoi2014]旅行
- BZOJ 3531 [Sdoi2014]旅行 树链剖分
- BZOJ[3531][Sdoi2014]旅行 树链剖分+动态开点线段树
- bzoj3531: [Sdoi2014]旅行