Dynamic LCA
Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on CodeForcesGym. Original ID: 100512D64-bit integer IO format: %I64d Java class name: (Any)
解题:LCT
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 200010; 4 struct arc { 5 int to,next; 6 arc(int x = 0,int y = -1) { 7 to = x; 8 next = y; 9 } 10 } e[maxn<<1]; 11 int head[maxn],tot; 12 void add(int u,int v) { 13 e[tot] = arc(v,head[u]); 14 head[u] = tot++; 15 } 16 struct LCT { 17 int fa[maxn],ch[maxn][2],parent[maxn],flip[maxn]; 18 inline void pushdown(int x) { 19 if(flip[x]) { 20 flip[ch[x][0]] ^= 1; 21 flip[ch[x][1]] ^= 1; 22 swap(ch[x][0],ch[x][1]); 23 flip[x] = 0; 24 } 25 } 26 void build(int u,int v) { 27 fa[v] = ch[v][0] = ch[v][1] = 0; 28 flip[v] = 0; 29 parent[v] = u; 30 } 31 void rotate(int x,int kd) { 32 int y = fa[x]; 33 pushdown(y); 34 pushdown(x); 35 ch[y][kd^1] = ch[x][kd]; 36 fa[ch[x][kd]] = y; 37 fa[x] = fa[y]; 38 ch[x][kd] = y; 39 fa[y] = x; 40 if(fa[x]) ch[fa[x]][y == ch[fa[x]][1]] = x; 41 } 42 void splay(int x,int goal = 0) { 43 int y = x; 44 while(fa[y]) y = fa[y]; 45 pushdown(x); 46 if(x != y) { 47 parent[x] = parent[y]; 48 parent[y] = 0; 49 while(fa[x] != goal) { 50 pushdown(fa[fa[x]]); 51 pushdown(fa[x]); 52 pushdown(x); 53 if(fa[fa[x]] == goal) rotate(x,x == ch[fa[x]][0]); 54 else { 55 int y = fa[x],z = fa[y],s = (y == ch[z][0]); 56 if(x == ch[y][s]) { 57 rotate(x,s^1); 58 rotate(x,s); 59 } else { 60 rotate(y,s); 61 rotate(x,s); 62 } 63 } 64 } 65 } 66 } 67 void access(int x) { 68 for(int y = 0; x; x = parent[x]) { 69 splay(x); 70 fa[ch[x][1]] = 0; 71 parent[ch[x][1]] = x; 72 ch[x][1] = y; 73 fa[y] = x; 74 parent[y] = 0; 75 y = x; 76 } 77 } 78 int LCA(int x,int y) { 79 access(y); 80 splay(y); 81 for(int z = x; z; z = parent[z]) { 82 splay(z); 83 if(!parent[z]) return z; 84 } 85 return -1; 86 } 87 void makeroot(int x) { 88 access(x); 89 splay(x); 90 flip[x] ^= 1; 91 } 92 void init(){ 93 memset(flip,0,sizeof flip); 94 memset(ch,0,sizeof ch); 95 memset(parent,0,sizeof parent); 96 memset(fa,0,sizeof fa); 97 } 98 } lct; 99 void dfs(int u,int fa) { 100 for(int i = head[u]; ~i; i = e[i].next) { 101 if(e[i].to == fa) continue; 102 lct.build(u,e[i].to); 103 dfs(e[i].to,u); 104 } 105 } 106 int main() { 107 #define NAME "dynamic" 108 freopen(NAME".in","r",stdin); 109 freopen(NAME".out","w",stdout); 110 int n,m,u,v; 111 char op[100]; 112 while(scanf("%d",&n),n) { 113 memset(head,-1,sizeof head); 114 tot = 0; 115 lct.init(); 116 for(int i = 1; i < n; ++i) { 117 scanf("%d%d",&u,&v); 118 add(u,v); 119 add(v,u); 120 } 121 lct.build(0,1); 122 dfs(1,1); 123 scanf("%d",&m); 124 while(m--) { 125 scanf("%s%d",op,&u); 126 if(op[0] == '!') lct.makeroot(u); 127 else if(op[0] == '?') { 128 scanf("%d",&v); 129 printf("%d ",lct.LCA(u,v)); 130 } 131 } 132 } 133 return 0; 134 } 135 /* 136 9 137 1 2 138 1 3 139 2 4 140 2 5 141 3 6 142 3 7 143 6 8 144 6 9 145 10 146 ? 4 5 147 ? 5 6 148 */