标签:
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
3
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\n",query(u,v));break; 137 default:; 138 } 139 } 140 } 141 return 0; 142 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4900658.html