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

5
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

2
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
",Ask(x));
143         else
144             scanf("%d%d",&x,&y),Change(x,y);
145     }
146 }
原文地址:https://www.cnblogs.com/refun/p/8678610.html