Little Devil I
Time Limit: 8000ms
Memory Limit: 131072KB
This problem will be judged on HDU. Original ID: 489764-bit integer IO format: %I64d Java class name: Main
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.
The devil likes to make thing in chaos. This kingdom’s road system is like simply a tree(connected graph without cycle). A road has a color of black or white. The devil often wants to make some change of this system.
In details, we call a path on the tree from a to b consists of vertices lie on the shortest simple path between a and b. And we say an edge is on the path if both its two endpoints is in the path, and an edge is adjacent to the path if exactly one endpoint of it is in the path.
Sometimes the devil will ask you to reverse every edge’s color on a path or adjacent to a path.
The king’s daughter, WJMZBMR, is also a cute loli, she is surprised by her father’s lolicon-like behavior. As she is concerned about the road-system’s status, sometimes she will ask you to tell there is how many black edge on a path.
Initially, every edges is white.
The devil likes to make thing in chaos. This kingdom’s road system is like simply a tree(connected graph without cycle). A road has a color of black or white. The devil often wants to make some change of this system.
In details, we call a path on the tree from a to b consists of vertices lie on the shortest simple path between a and b. And we say an edge is on the path if both its two endpoints is in the path, and an edge is adjacent to the path if exactly one endpoint of it is in the path.
Sometimes the devil will ask you to reverse every edge’s color on a path or adjacent to a path.
The king’s daughter, WJMZBMR, is also a cute loli, she is surprised by her father’s lolicon-like behavior. As she is concerned about the road-system’s status, sometimes she will ask you to tell there is how many black edge on a path.
Initially, every edges is white.
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n, which is the size of the tree. The vertices be indexed from 1.
On the next n-1 lines, each line contains two integers a,b, denoting there is an edge between a and b.
The next line contains an integer Q, denoting the number of the operations.
On the next Q lines, each line contains three integers t,a,b. t=1 means we reverse every edge’s color on path a to b. t=2 means we reverse every edge’s color adjacent to path a to b. t=3 means we query about the number of black edge on path a to b.
T<=5.
n,Q<=105.
Please use scanf,printf instead of cin,cout,because of huge input.
For each test case, the first line contains an integer n, which is the size of the tree. The vertices be indexed from 1.
On the next n-1 lines, each line contains two integers a,b, denoting there is an edge between a and b.
The next line contains an integer Q, denoting the number of the operations.
On the next Q lines, each line contains three integers t,a,b. t=1 means we reverse every edge’s color on path a to b. t=2 means we reverse every edge’s color adjacent to path a to b. t=3 means we query about the number of black edge on path a to b.
T<=5.
n,Q<=105.
Please use scanf,printf instead of cin,cout,because of huge input.
Output
For each t=3 operation, output the answer in one line.
Sample Input
1 10 2 1 3 1 4 1 5 1 6 5 7 4 8 3 9 5 10 6 10 2 1 6 1 3 8 3 8 10 2 3 4 2 10 8 2 4 10 1 7 6 2 7 3 2 1 4 2 10 10
Sample Output
3
Hint
reverse color means change from white to black or vice virsa.
Source
解题:树链剖分
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 101010; 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],cnt,tot; 12 void add(int u,int v) { 13 e[tot] = arc(v,head[u]); 14 head[u] = tot++; 15 } 16 int dep[maxn],fa[maxn],top[maxn],siz[maxn],son[maxn]; 17 int loc[maxn],sum[maxn<<2],flip[maxn<<2],light[maxn<<2]; 18 void FindHeavyEdge(int u,int father,int depth) { 19 dep[u] = depth; 20 fa[u] = father; 21 siz[u] = 1; 22 son[u] = -1; 23 for(int i = head[u]; ~i; i = e[i].next) { 24 if(e[i].to == father) continue; 25 FindHeavyEdge(e[i].to,u,depth + 1); 26 siz[u] += siz[e[i].to]; 27 if(son[u] == -1 || siz[son[u]] < siz[e[i].to]) 28 son[u] = e[i].to; 29 } 30 } 31 void ConnectHeavyEdge(int u,int ancestor){ 32 top[u] = ancestor; 33 loc[u] = ++cnt; 34 if(~son[u]) ConnectHeavyEdge(son[u],ancestor); 35 for(int i = head[u]; ~i; i = e[i].next){ 36 if(e[i].to == fa[u] || e[i].to == son[u]) continue; 37 ConnectHeavyEdge(e[i].to,e[i].to); 38 } 39 } 40 inline void pushdown(int v,int L,int M,int R){ 41 if(flip[v]){ 42 flip[v<<1] ^= 1; 43 flip[v<<1|1] ^= 1; 44 sum[v<<1] = (M - L + 1) - sum[v<<1]; 45 sum[v<<1|1] = (R - M) - sum[v<<1|1]; 46 flip[v] = 0; 47 } 48 if(light[v]){ 49 light[v<<1] ^= 1; 50 light[v<<1|1] ^= 1; 51 light[v] = 0; 52 } 53 } 54 inline void pushup(int v){ 55 sum[v] = sum[v<<1] + sum[v<<1|1]; 56 } 57 void update(bool OP,int L,int R,int lt,int rt,int v){ 58 if(lt <= L && rt >= R){ 59 if(OP){ 60 flip[v] ^= 1; 61 sum[v] = (R - L + 1) - sum[v]; 62 }else light[v] ^= 1; 63 return; 64 } 65 int mid = (L + R)>>1; 66 pushdown(v,L,mid,R); 67 if(lt <= mid) update(OP,L,mid,lt,rt,v<<1); 68 if(rt > mid) update(OP,mid + 1,R,lt,rt,v<<1|1); 69 pushup(v); 70 } 71 int query(bool OP,int L,int R,int lt,int rt,int v){ 72 if(lt <= L && rt >= R) return OP?sum[v]:light[v]; 73 int ret = 0,mid = (L + R)>>1; 74 pushdown(v,L,mid,R); 75 if(lt <= mid) ret = query(OP,L,mid,lt,rt,v<<1); 76 if(rt > mid) ret += query(OP,mid+1,R,lt,rt,v<<1|1); 77 return ret; 78 } 79 void modifyHeavy(int u,int v){ 80 while(top[u] != top[v]){ 81 if(dep[top[u]] < dep[top[v]]) swap(u,v); 82 update(true,1,cnt,loc[top[u]],loc[u],1); 83 u = fa[top[u]]; 84 } 85 if(u == v) return; 86 if(dep[u] > dep[v]) swap(u,v); 87 update(true,1,cnt,loc[son[u]],loc[v],1); 88 } 89 void modifyLight(int u,int v){ 90 while(top[u] != top[v]){ 91 if(dep[top[u]] < dep[top[v]]) swap(u,v); 92 update(false,1,cnt,loc[top[u]],loc[u],1); 93 if(~son[u]) update(true,1,cnt,loc[son[u]],loc[son[u]],1); 94 update(true,1,cnt,loc[top[u]],loc[top[u]],1); 95 u = fa[top[u]]; 96 } 97 if(dep[u] > dep[v]) swap(u,v); 98 update(false,1,cnt,loc[u],loc[v],1); 99 if(fa[u]) update(true,1,cnt,loc[u],loc[u],1); 100 if(~son[v]) update(true,1,cnt,loc[son[v]],loc[son[v]],1); 101 } 102 int query(int u,int v,int ret = 0){ 103 while(top[u] != top[v]){ 104 if(dep[top[u]] < dep[top[v]]) swap(u,v); 105 if(u != top[u]) ret += query(true,1,cnt,loc[son[top[u]]],loc[u],1); 106 ret += query(true,1,cnt,loc[top[u]],loc[top[u]],1)^query(false,1,cnt,loc[fa[top[u]]],loc[fa[top[u]]],1); 107 u = fa[top[u]]; 108 } 109 if(u == v) return ret; 110 if(dep[u] > dep[v]) swap(u,v); 111 return ret + query(true,1,cnt,loc[son[u]],loc[v],1); 112 } 113 int main() { 114 int kase,u,v,n,m,op; 115 scanf("%d",&kase); 116 while(kase--){ 117 memset(head,-1,sizeof head); 118 memset(sum,0,sizeof sum); 119 memset(flip,0,sizeof flip); 120 memset(light,0,sizeof light); 121 cnt = tot = 0; 122 scanf("%d",&n); 123 for(int i = 1; i < n; ++i){ 124 scanf("%d%d",&u,&v); 125 add(u,v); 126 add(v,u); 127 } 128 FindHeavyEdge(1,0,0); 129 ConnectHeavyEdge(1,1); 130 scanf("%d",&m); 131 while(m--){ 132 scanf("%d%d%d",&op,&u,&v); 133 switch(op){ 134 case 1:modifyHeavy(u,v);break; 135 case 2:modifyLight(u,v);break; 136 case 3:printf("%d ",query(u,v));break; 137 default:; 138 } 139 } 140 } 141 return 0; 142 }