[bzoj4551] [Tjoi2016&Heoi2016]树
这道题可以用树链剖分加线段树维护.
但是考虑到这道题的特殊性质,我们可以将操作离线反过来,用并查集维护.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<iomanip> #include<algorithm> #include<map> using namespace std; #define LL long long #define FILE "dealing" #define up(i,j,n) for(int i=j;i<=n;++i) #define db double #define ull unsigned long long #define eps 1e-10 #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f*x; } const int maxn=200200,mod=(int)(1e9+7+0.1),limit=(int)(1e6+1); int n,m; struct node{ int y,next; }e[maxn]; int len=0,linkk[maxn]; int fa[maxn],f[maxn]; void insert(int x,int y){ e[++len].y=y; e[len].next=linkk[x]; linkk[x]=len; } int getfa(int x){ return x==fa[x]?x:fa[x]=getfa(fa[x]); } void dfs(int x){ for(int i=linkk[x];i;i=e[i].next){ if(e[i].y==f[x])continue; f[e[i].y]=x; dfs(e[i].y); } } char ch[maxn]; int c[maxn],ans[maxn],Ci[maxn]; int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,2,n){ int x=read(),y=read(); insert(x,y);insert(y,x); } dfs(1); up(i,1,n)fa[i]=f[i]; fa[1]=f[1]=1;Ci[1]=1; up(i,1,m){ scanf(" %c",&ch[i]); c[i]=read(); if(ch[i]=='C') fa[c[i]]=c[i],Ci[c[i]]++; } for(int i=m;i>=1;i--){ if(ch[i]=='C'&&!--Ci[c[i]])fa[c[i]]=f[c[i]]; else ans[i]=getfa(c[i]); } up(i,1,m)if(ch[i]=='Q')printf("%d\n",ans[i]); return 0; }