[POI2007]MEG-Megalopolis (樹狀數組,Dfs序)
阿新 • • 發佈:2018-07-15
www ans turn ext std cout pan urn esp
題目描述
Solution
這道題考試的時候竟然沒有仔細想,結果只拿了暴力分...
其實就是一個 DFS序+樹狀數組。
我們先把用 DFS 把它變成一個序列,同時記錄它們的 \(siz\)。
那麽我們每一次連一條邊之後就是對它的子樹產生影響。
在樹狀數組裏面維護就好了。
代碼
#include<bits/stdc++.h> using namespace std; const int maxn=250008; struct sj{ int to; int next; }a[maxn*2]; int head[maxn],size; int n,m; void add1(int x,int y) { a[++size].to=y; a[size].next=head[x]; head[x]=size; } int id[maxn],tot; int siz[maxn],ans[maxn]; void dfs(int x) { id[x]=++tot; siz[x]=1; for(int i=head[x];i;i=a[i].next) { int tt=a[i].to; if(!siz[tt]) { ans[tt]=ans[x]+1; dfs(tt); siz[x]+=siz[tt]; } } } int c[maxn]; int lowbit(int x) {return x&(-x);} void add(int x,int z) {for(int i=x;i<=n;i+=lowbit(i))c[i]+=z;} int check(int x) { int sum=0; for(int i=x;i>=1;i-=lowbit(i)) sum+=c[i]; return sum; } int main() { scanf("%d",&n); for(int i=1;i<n;i++) {int x,y; scanf("%d%d",&x,&y);add1(x,y); add1(y,x);} dfs(1); for(int i=1;i<=n;i++) add(id[i],0); scanf("%d",&m); for(int i=1;i<=m+n-1;i++) { int x,y;char ch; cin>>ch; if(ch=='A') { scanf("%d%d",&x,&y); if(id[x]<id[y])swap(y,x); add(id[x],1); add(id[x]+siz[x],-1); } if(ch=='W') scanf("%d",&x), cout<<ans[x]-check(id[x])<<endl; } }
[POI2007]MEG-Megalopolis (樹狀數組,Dfs序)