题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1103
这题题目好长啊。。。第一眼我感觉树剖就好了,一看数据范围。。。然后想就想不出来了。。。感觉这题做法好妙啊!
首先求dfs序,比如样例就是1455422331,然后对于每个点,在它进入的时间+1,退出时-1,样例是:+1 +1 +1 -1 -1 +1 -1 +1 -1 -1
这样1~x的前缀和就是1到x的路径和了(想想为什么)
最后我们只要用一个树状数组来维护就好了
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #include<string> #include<ctime> #include<queue> #include<map> #include<set> #include<vector> #define mp make_pair #define fi first #define se second #define sqr(x) (x)*(x) #define rep(i,x,y) for (int i=(x);i<=(y);i++) #define per(i,x,y) for (int i=(x);i>=(y);i--) using namespace std; typedef long long LL; typedef double DBD; typedef pair<int,int> pa; const int inf=1e9; const LL INF=1e18; //----------------------------head-----------------------------------// const int N=250010,M=N<<1; struct edge{int to,nxt;}e[M]; int n,m,head[N],cnt,c[M],in[N],out[N],ind,ljj; char s[10]; int Write[20]; int read() {int d=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;} void write(int x){int t=0; if (x<0) putchar('-'),x=-x; for (;x;x/=10) Write[++t]=x%10; if (!t) putchar('0'); for (int i=t;i>=1;i--) putchar((char)(Write[i]+48));} void judge(){freopen(".in","r",stdin); freopen(".out","w",stdout);} void addedge(int x,int y) { e[++cnt]=(edge){y,head[x]}; head[x]=cnt; e[++cnt]=(edge){x,head[y]}; head[y]=cnt; } void dfs(int u,int fa) { in[u]=++ind; for (int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if (v==fa) continue; dfs(v,u); } out[u]=++ind; } void update(int x,int v){for (int i=x;i<=ljj;i+=i&-i) c[i]+=v;} int query(int x){int res=0; for (int i=x;i>=1;i-=i&-i) res+=c[i]; return res;} int main() { //judge(); n=read(); ljj=n*2; for (int i=1;i<n;i++) addedge(read(),read()); dfs(1,0); for (int i=1;i<=n;i++) update(in[i],1),update(out[i],-1); m=read(); m=n+m-1; while (m--) { scanf("%s",s); if (s[0]=='W') { int x=read(); printf("%d\n",query(in[x])-1); } else { int x=read(),y=read(); update(in[y],-1); update(out[y],1); } } return 0; } /* 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 */