HDU 4010 Query on The Trees(动态树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010

题意:一棵树,四种操作:

(1)若x和y不在一棵树上,将x和y连边;

(2)若x和y在一棵树上,将x变成树根,将y从x树上分离;

(3)若x和y在一棵树上,将x到y路径上的所有值增加det;

(4)若x和y在一棵树上,输出x到y路径上的最大值。

思路:1操作用link维护,2操作用cut,34操作先split(x,y),然后对y做tag,并且记录路径的max值。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<string>
  6 #include<algorithm>
  7 int tot,go[600005],next[600005],first[300005];
  8 int ch[600005][2],rev[600005],tag[600005],q[600005];
  9 int st[600005],mx[600005],fa[600005],v[600005];
 10 bool pd(int x){
 11     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
 12 }
 13 void insert(int x,int y){
 14     tot++;go[tot]=y;next[tot]=first[x];first[x]=tot;
 15 }
 16 void addedge(int x,int y){
 17     insert(x,y);insert(y,x);
 18 }
 19 void pushdown(int x){
 20     int l=ch[x][0],r=ch[x][1];
 21     if (rev[x]){
 22         rev[x]^=1;rev[l]^=1;rev[r]^=1;
 23         std::swap(ch[x][0],ch[x][1]);
 24     }
 25     if (tag[x]){
 26         if (l) tag[l]+=tag[x],v[l]+=tag[x],mx[l]+=tag[x];
 27         if (r) tag[r]+=tag[x],mx[r]+=tag[x],v[r]+=tag[x];
 28         tag[x]=0;
 29     }
 30 }
 31 void updata(int x){
 32     int l=ch[x][0],r=ch[x][1];
 33     mx[x]=std::max(v[x],std::max(mx[l],mx[r]));
 34 }
 35 void rotate(int x){
 36     int y=fa[x],z=fa[y],l,r;
 37     if (ch[y][0]==x) l=0;else l=1;r=l^1;
 38     if (!pd(y)){
 39         if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
 40     }
 41     fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
 42     ch[y][l]=ch[x][r];ch[x][r]=y;
 43     updata(y);updata(x);
 44 }
 45 void splay(int x){
 46     int top=0;st[++top]=x;
 47     for (int i=x;!pd(i);i=fa[i])
 48      st[++top]=fa[i];
 49     for (int i=top;i;i--)
 50      pushdown(st[i]);
 51     while (!pd(x)){
 52         int y=fa[x],z=fa[y];
 53         if (!pd(y)){
 54             if (ch[y][0]==x^ch[z][0]==y) rotate(x);
 55             else rotate(y);
 56         }
 57         rotate(x);
 58     }  
 59 }
 60 void access(int x){
 61     for (int t=0;x;t=x,x=fa[x]){
 62         splay(x);
 63         ch[x][1]=t;
 64         updata(x);
 65     }
 66 }
 67 void makeroot(int x){
 68     access(x);splay(x);rev[x]^=1;
 69 }
 70 void cut(int x,int y){
 71     makeroot(x);access(y);splay(y);ch[y][0]=fa[ch[y][0]]=0;updata(y);
 72 }
 73 void link(int x,int y){
 74     makeroot(x);
 75     fa[x]=y;
 76 }
 77 int find(int x){
 78     access(x);splay(x);
 79     while (ch[x][0]) x=ch[x][0];
 80     return x;
 81 }
 82 void add(int x,int y,int val){
 83     makeroot(x);access(y);splay(y);
 84     mx[y]+=val;v[y]+=val;tag[y]+=val;
 85 }
 86 int main(){
 87     int n,x,y,m,opt,w;
 88     while (scanf("%d",&n)!=EOF){
 89         mx[0]=-2000000000;
 90         for (int i=0;i<=n;i++) 
 91          mx[i]=tag[i]=rev[i]=v[i]=ch[i][0]=ch[i][1]=fa[i]=0;
 92         memset(first,0,sizeof first);tot=0;
 93         for (int i=1;i<n;i++){
 94          scanf("%d%d",&x,&y);
 95          addedge(x,y);
 96         }
 97         for (int i=1;i<=n;i++){
 98             scanf("%d",&v[i]);
 99             mx[i]=v[i];
100         }
101         int top=1;
102         q[top]=1;
103         for (int k=1;k<=top;k++){
104             for (int i=first[q[k]];i;i=next[i]){
105                 int pur=go[i];
106                 if (pur==fa[q[k]]) continue;
107                 fa[pur]=q[k];
108                 q[++top]=pur;
109             }
110         }
111         top=0;
112         scanf("%d",&m);
113         while (m--){
114             scanf("%d",&opt);
115             if (opt==1){
116                 scanf("%d%d",&x,&y);
117                 if (find(x)==find(y)) {puts("-1");continue;}
118                 link(x,y);
119             }
120             else
121             if (opt==2){
122                 scanf("%d%d",&x,&y);
123                 if (find(x)!=find(y)||x==y) {puts("-1");continue;}
124                 cut(x,y);
125             }
126             else
127             if (opt==3){
128                 scanf("%d%d%d",&w,&x,&y);
129                 if (find(x)!=find(y)){puts("-1");continue;}
130                 add(x,y,w);
131             }
132             else
133             if (opt==4)
134             {
135                 scanf("%d%d",&x,&y);
136                 if (find(x)!=find(y)){
137                     printf("-1
");
138                     continue;
139                 }
140                 makeroot(x);access(y);splay(y);
141                 printf("%d
",mx[y]);
142             }
143         }
144         printf("
");
145     }
146 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5537899.html