BZOJ 1103: [POI2007]大都市meg
Description
在經濟全球化浪潮的影響下,習慣于漫步在清晨的鄉間小路的郵遞員Blue Mary也開始騎著摩托車傳遞郵件了。
不過,她經?;貞浧鹨郧霸卩l間漫步的情景。昔日,鄉下有依次編號為1..n的n個小村莊,某些村莊之間有一些雙
向的土路。從每個村莊都恰好有一條路徑到達村莊1(即比特堡)。并且,對于每個村莊,它到比特堡的路徑恰好
只經過編號比它的編號小的村莊。另外,對于所有道路而言,它們都不在除村莊以外的其他地點相遇。在這個未開
化的地方,從來沒有過高架橋和地下鐵道。隨著時間的推移,越來越多的土路被改造成了公路。至今,Blue Mary
還清晰地記得最后一條土路被改造為公路的情景?,F在,這里已經沒有土路了——所有的路都成為了公路,而昔日
的村莊已經變成了一個大都市。 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
51 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
21
0
1
HINT
?
?
?
?
?
?
?
?
?
?
Solution:
本題翻譯有毒。我解釋一波題意:給定一棵根節點為$1$,$n$個節點的樹,原本每條邊長度為$1$,有$m+n-1$次操作,每次修改一條邊使得邊權為$0$,或者查詢$1$到某個點的距離(邊權和)。
不難發現,每次修改一條邊(假設是$u->v$),到根節點距離會減少的點實際上就是以$v$為根節點的子樹上的所有的點。
于是我們先求出$dfs$序,得到每棵子樹,并統計每個子樹的大小。
然后對$dfs$序離散一下,這樣保證離散后的$dfs$序從小到大排列,使得子樹之間不會有交集,便可以用一棵線段樹維護所有子樹的信息。
那么每次操作時,就是區間修改和單點查詢了,每次輸出的是所需節點子樹大小$-$單點查詢的值。
代碼:
?
#include<bits/stdc++.h> #define il inline #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) using namespace std; const int N=250005; int n,dfn[N<<2],ct,cnt,h[N],to[N],net[N],dep[N],tot[N]; int mp[N],add[N<<2],sum[N<<2],p,m; char s[4]; il int gi(){int a=0;char x=getchar();while(x<'0'||x>'9')x=getchar();while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();return a; } il void addd(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;} il void dfs1(int x){dfn[++ct]=x;tot[x]=1;for(int i=h[x];i;i=net[i])dep[to[i]]=dep[x]+1,dfs1(to[i]),tot[x]+=tot[to[i]];dfn[++ct]=x; } il void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];} il void pushdown(int rt,int k){if(add[rt]){add[rt<<1]+=add[rt];add[rt<<1|1]+=add[rt];sum[rt<<1]+=add[rt]*(k-(k>>1));sum[rt<<1|1]+=add[rt]*(k>>1);add[rt]=0;} } il void update(int L,int R,int c,int l,int r,int rt){if(L<=l&&R>=r){add[rt]+=c;sum[rt]+=c*(r-l+1);return;}pushdown(rt,r-l+1);int m=l+r>>1;if(L<=m)update(L,R,c,lson);if(m<R)update(L,R,c,rson);pushup(rt); } il int query(int L,int R,int l,int r,int rt){if(L<=l&&R>=r)return sum[rt];pushdown(rt,r-l+1);int m=l+r>>1,ret=0;if(L<=m)ret+=query(L,R,lson);if(m<R)ret+=query(L,R,rson);return ret; } int main(){n=gi();int u,v;For(i,1,n-1)u=gi(),v=gi(),addd(u,v);dfs1(1);For(i,1,ct)if(!mp[dfn[i]])mp[dfn[i]]=++p,dfn[i]=p;else dfn[i]=mp[dfn[i]];m=gi()+n-1;while(m--){scanf("%s",s);if(s[0]=='W'){u=gi();printf("%d\n",dep[u]-query(mp[u],mp[u],1,n,1));}else{u=gi();v=gi();if(u<v)swap(u,v);update(mp[u],mp[u]+tot[u]-1,1,1,n,1);}}return 0; }?
轉載于:https://www.cnblogs.com/five20/p/9045377.html
總結
以上是生活随笔為你收集整理的BZOJ 1103: [POI2007]大都市meg的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: element-ui中单独引入Messa
- 下一篇: WFA 认证 启动 sigma_dut方