【BZOJ1103】大都市meg
1103: [POI2007]大都市meg
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2310 Solved: 1223
[Submit][Status][Discuss]
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
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
1
0
1
HINT
Source
我讲个笑话 给gcc开无限栈空间评测然后给g++开有限空间 然后看着自己RE
再讲个笑话 dfs不会爆栈
如果数据范围较小,可以树链剖分
由于较大 所以说dfs序
/************************************************************** Problem: 1103 User: redwind Language: C++ Result: Accepted Time:8644 ms Memory:50140 kb ****************************************************************/ /*To The End Of The Galaxy*/ #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<iomanip> #include<stack> #include<map> #include<time.h> #include<set> #include<cmath> #define debug(x) cerr<<#x<<"="<<x<<endl #define INF 0x7f7f7f7f #define llINF 0x7fffffffffffll #define P(x,y) (((x-1)*m)+y) using namespace std; typedef pair<int,int> pii; typedef long long ll; inline int init() { int now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } inline long long llinit() { long long now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } struct edge { int from,to,val,pre; }Edge[500005]; int cnt=0,dis[250002],head[250002]; inline void addedge(int from,int to,int val) { ++cnt; Edge[cnt]=((edge){from,to,val,head[from]}); head[from]=cnt; } int dfn[250005],last[250005],dfs_time=0,pre[250005]; void dfs(int now,int fa,int depth) { dfn[now]=++dfs_time; dis[dfn[now]]=depth; for(int j=head[now];j;j=Edge[j].pre) { if(Edge[j].to==fa)continue; else { dfs(Edge[j].to,now,depth+1); pre[Edge[j].to]=now; } } last[now]=dfs_time; } //--------dfs--------------------------------------------- #define mid ((l+r)>>1) #define lson (now<<1) #define rson (now<<1|1) char type[10]; struct segment { int l,r,val,lazy; }tree[2000008]; void update(int now) { tree[now].val=tree[lson].val+tree[rson].val; } void calc(int now,int delta) { tree[now].val+=(tree[now].r-tree[now].l+1)*delta; tree[now].lazy+=delta; } void push_down(int now) { calc(lson,tree[now].lazy); calc(rson,tree[now].lazy); tree[now].lazy=0; } void build(int l,int r,int now) { tree[now].l=l;tree[now].r=r; if(l==r) { tree[now].val=dis[l]; return; } else { build(l,mid,lson); build(mid+1,r,rson); update(now); } } void addtag(int l,int r,int x,int y,int now,int delta) { push_down(now); if(l==x&&r==y) { calc(now,delta); return; } else { if(y<=mid)addtag(l,mid,x,y,lson,delta); else if(x>mid)addtag(mid+1,r,x,y,rson,delta); else addtag(l,mid,x,mid,lson,delta),addtag(mid+1,r,mid+1,y,rson,delta); update(now); } } int query(int l,int r,int x,int y,int now) { push_down(now); if(l==x&&r==y) { return tree[now].val; } else { if(y<=mid)return query(l,mid,x,y,lson); else if(x>mid)return query(mid+1,r,x,y,rson); else return query(l,mid,x,mid,lson)+query(mid+1,r,mid+1,y,rson); } } //---------------------segment tree-------------------------- int main() { int a,b,n,m; n=init(); for(int i=1;i<n;i++) { a=init();b=init(); addedge(a,b,1); addedge(b,a,1); } dfs(1,0,0); m=init(); m=n+m-1; build(1,n,1); for(int i=1;i<=m;i++) { scanf("%s",type+1); if(type[1]=='W') { a=init(); printf("%d\n",query(1,n,dfn[a],dfn[a],1)); } else { a=init();b=init(); addtag(1,n,dfn[b],last[b],1,-1); } } return 0; }