1103. [POI2007]MEG-Megalopolis【树链剖分】
Description
在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双
向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好
只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开
化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary
还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日
的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,
并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需
要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)
Input
第一行是一个数n(1 < = n < = 2 50000).以下n-1行,每行两个整数a,b(1 < = a以下一行包含一个整数m
(1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息
,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到
村庄a。
Output
有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。
Sample Input
1 2
1 3
1 4
4 5
4
W 5
A 1 4
W 5
A 4 5
W 5
W 2
A 1 2
A 1 3
Sample Output
1
0
1
HINT
就是一道裸的树链剖分啊……
过程中唯一的一点小麻烦(好像也算不上麻烦)
就是把边看成点做0v0
所以Change的时候最后当两个点在同一条重链上就修改
Update(1,1,n,T_NUM[Son[x]],T_NUM[y],1);
1 #include<iostream> 2 #include<cstdio> 3 #define MAX (250000+10) 4 using namespace std; 5 6 int Depth[MAX],Son[MAX],Father[MAX],Sum[MAX]; 7 int head[MAX],num_edge,sum; 8 int Top[MAX],T_NUM[MAX],n; 9 struct node 10 { 11 int to,next; 12 }edge[MAX*2]; 13 struct node1 14 { 15 int add,down; 16 }Segt[MAX*4]; 17 18 void Add(int u,int v) 19 { 20 edge[++num_edge].to=v; 21 edge[num_edge].next=head[u]; 22 head[u]=num_edge; 23 } 24 25 void Dfs1(int x) 26 { 27 Depth[x]=Depth[Father[x]]+1; 28 Sum[x]=1; 29 for (int i=head[x];i!=0;i=edge[i].next) 30 if (edge[i].to!=Father[x]) 31 { 32 Father[edge[i].to]=x; 33 Dfs1(edge[i].to); 34 Sum[x]+=Sum[edge[i].to]; 35 if (Son[x]==0 || Sum[Son[x]]<Sum[edge[i].to]) 36 Son[x]=edge[i].to; 37 } 38 } 39 40 void Dfs2(int x,int pre) 41 { 42 T_NUM[x]=++sum; 43 Top[x]=pre; 44 if (Son[x]!=0) 45 Dfs2(Son[x],pre); 46 for (int i=head[x];i!=0;i=edge[i].next) 47 { 48 if (edge[i].to!=Father[x] && edge[i].to!=Son[x]) 49 Dfs2(edge[i].to,edge[i].to); 50 } 51 } 52 53 void Pushdown(int node,int l,int r) 54 { 55 if (Segt[node].down!=0) 56 { 57 Segt[node*2].down=Segt[node].down; 58 Segt[node*2+1].down=Segt[node].down; 59 int mid=(l+r)/2; 60 Segt[node*2].add=Segt[node].down*(mid-l+1); 61 Segt[node*2].add=Segt[node].down*(r-mid); 62 Segt[node].down=0; 63 } 64 } 65 66 void Update(int node,int l,int r,int l1,int r1,int k) 67 { 68 if (r<l1 || l>r1) 69 return; 70 if (l1<=l && r<=r1) 71 { 72 Segt[node].add=(r-l+1)*k; 73 Segt[node].down=k; 74 return; 75 } 76 Pushdown(node,l,r); 77 int mid=(l+r)/2; 78 Update(node*2,l,mid,l1,r1,k); 79 Update(node*2+1,mid+1,r,l1,r1,k); 80 Segt[node].add=Segt[node*2].add+Segt[node*2+1].add; 81 } 82 83 int Query(int node,int l,int r,int l1,int r1) 84 { 85 if (r<l1 || l>r1) 86 return 0; 87 if (l1<=l && r<=r1) 88 return Segt[node].add; 89 Pushdown(node,l,r); 90 int mid=(l+r)/2; 91 return Query(node*2,l,mid,l1,r1)+ 92 Query(node*2+1,mid+1,r,l1,r1); 93 94 } 95 96 void Change(int x,int y) 97 { 98 int fx=Top[x],fy=Top[y]; 99 while (fx!=fy) 100 { 101 if (Depth[fx]<Depth[fy]) 102 swap(fx,fy),swap(x,y); 103 Update(1,1,n,T_NUM[fx],T_NUM[x],1); 104 x=Father[fx];fx=Top[x]; 105 } 106 if (Depth[x]>Depth[y]) 107 swap(x,y); 108 Update(1,1,n,T_NUM[Son[x]],T_NUM[y],1); 109 } 110 111 int Ask(int x)//0为土路1为公路 112 { 113 int ans=0,fx=Top[x],sum=Depth[x]-1; 114 while (x!=0) 115 { 116 ans+=Query(1,1,n,T_NUM[fx],T_NUM[x]); 117 x=Father[fx],fx=Top[x]; 118 } 119 return sum-ans; 120 } 121 122 int main() 123 { 124 int u,v,m,x,y; 125 char p; 126 scanf("%d",&n); 127 for (int i=1;i<=n-1;++i) 128 { 129 scanf("%d%d",&u,&v); 130 Add(u,v); 131 Add(v,u); 132 } 133 Dfs1(1); 134 Dfs2(1,1); 135 scanf("%d",&m); 136 for (int i=1;i<=n+m-1;++i) 137 { 138 scanf("%c",&p); 139 while (p!='W' && p!='A') 140 scanf("%c",&p); 141 if (p=='W') 142 scanf("%d",&x),printf("%d\n",Ask(x)); 143 else 144 scanf("%d%d",&x,&y),Change(x,y); 145 } 146 }