BZOJ1103 大都市
問題描述
在經濟全球化浪潮的影響下,習慣於漫步在清晨的鄉間小路的郵遞員Blue Mary也開始騎着摩托車傳遞郵件了。
不過,她經常回憶起以前在鄉間漫步的情景。昔日,鄉下有依次編號爲1..n的n個小村莊,某些村莊之間有一些雙向的土路。從每個村莊都恰好有一條路徑到達村莊1(即比特堡)。並且,對於每個村莊,它到比特堡的路徑恰好只經過編號比它的編號小的村莊。另外,對於所有道路而言,它們都不在除村莊以外的其他地點相遇。在這個未開化的地方,從來沒有過高架橋和地下鐵道。隨着時間的推移,越來越多的土路被改造成了公路。至今,Blue Mary還清晰地記得最後一條土路被改造爲公路的情景。現在,這裏已經沒有土路了——所有的路都成爲了公路,而昔日的村莊已經變成了一個大都市。
Blue Mary想起了在改造期間她送信的經歷。她從比特堡出發,需要去某個村莊,並且在兩次送信經歷的間隔期間,有某些土路被改造成了公路.
現在Blue Mary需要你的幫助:計算出每次送信她需要走過的土路數目。(對於公路,她可以騎摩托車;而對於土路,她就只好推車了。)
輸入格式
第一行是一個數n(1 < = n < = 2 50000).
以下n-1行,每行兩個整數a,b(1 < =a < b <=n) 以下一行包含一個整數m(1 < = m < = 2 50000),表示Blue Mary曾經在改造期間送過m次信。
以下n+m-1行,每行有兩種格式的若干信息,表示按時間先後發生過的n+m-1次事件:若這行爲 A a b,表示道路a b被改成了公路。若這行爲 W a, 則表示Blue Mary曾經從比特堡送信到村莊a。
輸出格式
有m行,每行包含一個整數,表示對應的某次送信時經過的土路數目。
樣例輸入
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
樣例輸出
2
1
0
1
樹鏈剖分當然是可以搞的。但是這樣會比較卡。
考慮把一條邊改成公路的影響,設這條邊連接的較深的節點爲
實現區間修改的操作,常常採用兩種方式:
1.線段樹
2.差分數組
差分數組本來是修改
有了樹狀數組當然就不選線段樹了。
#include<stdio.h>
#define MAXN 250005
#define MAXM 500005
int N,M;
int en[MAXM],nex[MAXM],las[MAXN],tot;
void ADD(int x,int y)
{
en[++tot]=y;
nex[tot]=las[x];
las[x]=tot;
}
int In[MAXN],Out[MAXN],dep[MAXN],VT;
void DFS(int x,int f)
{
int i,y;
In[x]=++VT;dep[x]=dep[f]+1;
for(i=las[x];i;i=nex[i])
{
y=en[i];
if(y!=f)DFS(y,x);
}
Out[x]=VT;
}
int C[MAXN];
void Modify(int x,int k){for(int i=x;i<=N;i+=(i&-i))C[i]+=k;}
int GetSum(int x)
{
int i,sum=0;
for(i=x;i;i-=(i&-i))sum+=C[i];
return sum;
}
int mian()
{
int i,x,y,a,b;
char op[3];
scanf("%d",&N);
for(i=1;i<N;i++)
{
scanf("%d%d",&x,&y);
ADD(x,y);ADD(y,x);
}
DFS(1,0);
for(i=2;i<=N;i++)Modify(In[i],1),Modify(Out[i]+1,-1);
scanf("%d",&M);
for(i=1;i<=N+M-1;i++)
{
scanf("%s",op);
if(op[0]=='W')
{
scanf("%d",&x);
printf("%d\n",GetSum(In[x]));
}
else
{
scanf("%d%d",&x,&y);
if(In[x]<In[y])a=In[y],b=Out[y];
else a=In[x],b=Out[x];
Modify(a,-1);
Modify(b+1,1);
}
}
}
const int main_stack=16;
char my_stack[128<<20];
int main() {
__asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");
__asm__("movl %%eax, %%esp;\n"::"a"(my_stack+sizeof(my_stack)-main_stack):"%esp");
mian();
__asm__("movl (%%eax), %%esp;\n"::"a"(my_stack):"%esp");
return 0;
}