Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 4091 Accepted Submission(s): 1774
题解:
LCT的子树问题。
找到每个点所在的原始树(不是Splay树)的根。
又是子树判断最麻烦。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 300010 4 #define INF 1e9 5 struct node 6 { 7 int left,right,val,mx; 8 }tree[MAXN]; 9 struct NODE 10 { 11 int begin,end,next; 12 }edge[MAXN*2]; 13 int father[MAXN],rev[MAXN],tag[MAXN],U[MAXN],V[MAXN],Stack[MAXN],Head[MAXN],cnt; 14 void addedge(int bb,int ee) 15 { 16 edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt; 17 } 18 void addedge1(int bb,int ee) 19 { 20 addedge(bb,ee);addedge(ee,bb); 21 } 22 int read() 23 { 24 int s=0,fh=1;char ch=getchar(); 25 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)fh=-1;ch=getchar();} 26 while(ch>=‘0‘&&ch<=‘9‘){s=s*10+(ch-‘0‘);ch=getchar();} 27 return s*fh; 28 } 29 int isroot(int x) 30 { 31 return tree[father[x]].left!=x&&tree[father[x]].right!=x; 32 } 33 void pushdown(int x) 34 { 35 int l=tree[x].left,r=tree[x].right; 36 if(rev[x]!=0) 37 { 38 rev[x]^=1;rev[l]^=1;rev[r]^=1; 39 swap(tree[x].left,tree[x].right); 40 } 41 if(tag[x]!=0) 42 { 43 /*tag[l]+=tag[x];tag[r]+=tag[x]; 44 tree[l].val+=tag[x];tree[r].val+=tag[x]; 45 tree[l].mx+=tag[x];tree[r].mx+=tag[x];*/ 46 if(l!=0){tag[l]+=tag[x];tree[l].val+=tag[x];tree[l].mx+=tag[x];} 47 if(r!=0){tag[r]+=tag[x];tree[r].val+=tag[x];tree[r].mx+=tag[x];} 48 tag[x]=0; 49 } 50 } 51 void Pushup(int x) 52 { 53 int l=tree[x].left,r=tree[x].right; 54 tree[x].mx=max(max(tree[l].mx,tree[r].mx),tree[x].val); 55 } 56 void rotate(int x) 57 { 58 int y=father[x],z=father[y]; 59 if(!isroot(y)) 60 { 61 if(tree[z].left==y)tree[z].left=x; 62 else tree[z].right=x; 63 } 64 if(tree[y].left==x) 65 { 66 father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y; 67 } 68 else 69 { 70 father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y; 71 } 72 Pushup(y);Pushup(x); 73 } 74 void splay(int x) 75 { 76 int top=0,i,y,z;Stack[++top]=x; 77 for(i=x;!isroot(i);i=father[i])Stack[++top]=father[i]; 78 for(i=top;i>=1;i--)pushdown(Stack[i]); 79 while(!isroot(x)) 80 { 81 y=father[x];z=father[y]; 82 if(!isroot(y)) 83 { 84 if((tree[y].left==x)^(tree[z].left==y))rotate(x); 85 else rotate(y); 86 } 87 rotate(x); 88 } 89 } 90 void access(int x) 91 { 92 int last=0; 93 while(x!=0) 94 { 95 splay(x); 96 tree[x].right=last;Pushup(x); 97 last=x;x=father[x]; 98 } 99 } 100 void makeroot(int x) 101 { 102 access(x);splay(x);rev[x]^=1; 103 } 104 void link(int u,int v) 105 { 106 /*access(u);*/makeroot(u);father[u]=v;//splay(u); 107 } 108 void cut(int u,int v) 109 { 110 /*access(u);*/makeroot(u);access(v);splay(v);/*father[u]=tree[v].left=0;*/father[tree[v].left]=0;tree[v].left=0;Pushup(v); 111 } 112 int findroot(int x) 113 { 114 access(x);splay(x); 115 while(tree[x].left!=0)x=tree[x].left; 116 return x; 117 } 118 int main() 119 { 120 int n,i,w,x,y,fh,Q,top=0,u,j,v; 121 while(scanf("%d",&n)!=EOF) 122 { 123 top=0; 124 for(i=0;i<=n;i++)tree[i].val=tree[i].mx=tree[i].left=tree[i].right=rev[i]=tag[i]=father[i]=0; 125 tree[0].mx=-INF; 126 memset(Head,-1,sizeof(Head));cnt=1; 127 for(i=1;i<n;i++) 128 { 129 U[i]=read();V[i]=read(); 130 addedge1(U[i],V[i]); 131 } 132 Stack[++top]=1; 133 for(i=1;i<=top;i++) 134 { 135 u=Stack[i]; 136 for(j=Head[u];j!=-1;j=edge[j].next) 137 { 138 v=edge[j].end; 139 if(v!=father[u]) 140 { 141 father[v]=u; 142 Stack[++top]=v; 143 } 144 } 145 } 146 for(i=1;i<=n;i++)tree[i].mx=tree[i].val=read(); 147 //for(i=1;i<n;i++)link(U[i],V[i]); 148 Q=read(); 149 for(i=1;i<=Q;i++) 150 { 151 fh=read(); 152 if(fh==1) 153 { 154 x=read();y=read(); 155 if(findroot(x)!=findroot(y))link(x,y); 156 else {printf("-1\n");continue;} 157 } 158 else if(fh==2) 159 { 160 x=read();y=read(); 161 if(findroot(x)==findroot(y)&&x!=y) 162 { 163 /*makeroot(x);*/cut(x,y); 164 //access(y);access(father[y]);splay(father[y]);father[y]=tree[father[y]].left=0; 165 } 166 else {printf("-1\n");continue;} 167 } 168 else if(fh==3) 169 { 170 w=read();x=read();y=read(); 171 if(findroot(x)==findroot(y)) 172 { 173 makeroot(x);access(y);splay(y); 174 tag[y]+=w;tree[y].mx+=w;tree[y].val+=w; 175 } 176 else {printf("-1\n");continue;} 177 } 178 else 179 { 180 x=read();y=read(); 181 makeroot(x);access(y);splay(y); 182 if(findroot(x)!=findroot(y)){printf("-1\n");continue;} 183 printf("%d\n",tree[y].mx); 184 } 185 } 186 printf("\n"); 187 } 188 return 0; 189 }
Hdu 4010-Query on The Trees LCT,动态树
原文:http://www.cnblogs.com/Var123/p/5294762.html