标签:cas make put who track mem key mode dal
LCT:
分割、合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值
5 1 2 2 4 2 5 1 3 1 2 3 4 5 6 4 2 3 2 1 2 4 2 3 1 3 5 3 2 1 4 4 1 4
3 -1 7HintWe define the illegal situation of different operations: In first operation: if node x and y belong to a same tree, we think it‘s illegal. In second operation: if x = y or x and y not belong to a same tree, we think it‘s illegal. In third operation: if x and y not belong to a same tree, we think it‘s illegal. In fourth operation: if x and y not belong to a same tree, we think it‘s illegal.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=330000; int ch[maxn][2],pre[maxn],key[maxn]; int add[maxn],rev[maxn],Max[maxn]; bool rt[maxn]; void update_add(int r,int d) { if(!r) return ; key[r]+=d; add[r]+=d; Max[r]+=d; } void update_rev(int r) { if(!r) return ; swap(ch[r][0],ch[r][1]); rev[r]^=1; } void push_down(int r) { if(add[r]) { update_add(ch[r][0],add[r]); update_add(ch[r][1],add[r]); add[r]=0; } if(rev[r]) { update_rev(ch[r][0]); update_rev(ch[r][1]); rev[r]=0; } } void push_up(int r) { Max[r]=max(max(Max[ch[r][0]],Max[ch[r][1]]),key[r]); } void Rotate(int x) { int y=pre[x],kind=(ch[y][1]==x); ch[y][kind]=ch[x][!kind]; pre[ch[y][kind]]=y; pre[x]=pre[y]; pre[y]=x; ch[x][!kind]=y; if(rt[y]) rt[y]=false,rt[x]=true; else ch[pre[x]][ch[pre[x]][1]==y]=x; push_up(y); } void P(int r) { if(!rt[r]) P(pre[r]); push_down(r); } void Splay(int r) { P(r); while(!rt[r]) { int f=pre[r],ff=pre[f]; if(rt[f]) Rotate(r); else if((ch[ff][1]==f)==(ch[f][1]==r)) Rotate(f),Rotate(r); else Rotate(r),Rotate(r); } push_up(r); } int Access(int x) { int y=0; for(;x;x=pre[y=x]) { Splay(x); rt[ch[x][1]]=true; rt[ch[x][1]=y]=false; push_up(x); } return y; } bool judge(int u,int v) { while(pre[u]) u=pre[u]; while(pre[v]) v=pre[v]; return u==v; } void mroot(int r) { Access(r); Splay(r); update_rev(r); } void lca(int &u,int &v) { Access(v); v=0; while(u) { Splay(u); if(!pre[u]) return ; rt[ch[u][1]]=true; rt[ch[u][1]=v]=false; push_up(u); u=pre[v=u]; } } void link(int u,int v) { if(judge(u,v)) { puts("-1"); return ; } mroot(u); pre[u]=v; } void cut(int u,int v) { if(u==v||!judge(u,v)) { puts("-1"); return ; } mroot(u); Splay(v); pre[ch[v][0]]=pre[v]; pre[v]=0; rt[ch[v][0]]=true; ch[v][0]=0; push_up(v); } void Add(int u,int v,int w) { if(!judge(u,v)) { puts("-1"); return ; } lca(u,v); update_add(ch[u][1],w); update_add(v,w); key[u]+=w; push_up(u); } void query(int u,int v) { if(!judge(u,v)) { puts("-1"); return ; } lca(u,v); printf("%d\n",max(max(Max[v],Max[ch[u][1]]),key[u])); } struct Edge { int to,next; }edge[maxn*2]; int Adj[maxn],Size=0; void init() { memset(Adj,-1,sizeof(Adj)); Size=0; } void add_edge(int u,int v) { edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++; } void dfs(int u) { for(int i=Adj[u];~i;i=edge[i].next) { int v=edge[i].to; if(pre[v]!=0) continue; pre[v]=u; dfs(v); } } int n; int main() { while(scanf("%d",&n)!=EOF) { init(); for(int i=0;i<n+10;i++) { pre[i]=0; ch[i][0]=ch[i][1]=0; rev[i]=0; add[i]=0; rt[i]=true; } for(int i=0;i<n-1;i++) { int u,v; scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } pre[1]=-1; dfs(1); pre[1]=0; for(int i=1;i<=n;i++) { scanf("%d",key+i); Max[i]=key[i]; } int q; scanf("%d",&q); while(q--) { int op; scanf("%d",&op); if(op==1) { int x,y; scanf("%d%d",&x,&y); link(x,y); } else if(op==2) { int x,y; scanf("%d%d",&x,&y); cut(x,y); } else if(op==3) { int x,y,w; scanf("%d%d%d",&w,&x,&y); Add(x,y,w); } else if(op==4) { int x,y; scanf("%d%d",&x,&y); query(x,y); } } putchar(10); } return 0; }
HDOJ 4010 Query on The Trees LCT
标签:cas make put who track mem key mode dal
原文地址:http://www.cnblogs.com/liguangsunls/p/7327884.html