Main topic
A tree, the root node is initially white point, the root node is a black point.
Each time a knot is dyed black or the nearest black ancestor asking for a knot.
Reverse Processing
Do it backwards, so each time it is dyed white a knot.
Then check it out!
#include <cstdio>#include <algorithm>#define FO (i,a,b) for (i=a;i<=b;i++)#define FD (I,A,B) for (i=a;i>=b;i--)using namespace STD;Const intmaxn=100000+Ten;structdong{intX,ans;BOOLP;} ASK[MAXN];intFA[MAXN],FATHER[MAXN],BZ[MAXN];inth[maxn],go[maxn*2],next[maxn*2];intI,j,k,l,t,n,m,tot;CharChvoidAddintXintY) {go[++tot]=y; NEXT[TOT]=H[X]; H[x]=tot;}voidDfsintXintY) {father[x]=y;intT=H[X]; while(t) {if(go[t]!=y) DFS (GO[T],X); T=NEXT[T]; }}voiddgintXintY) {if(!bz[x]) fa[x]=father[x];intT=H[X]; while(t) {if(go[t]!=y) DG (GO[T],X); T=NEXT[T]; }}intGETFA (intx) {returnFA[X]?FA[X]=GETFA (Fa[x]): x;}CharGet () {CharCh=getchar (); while(ch!=' Q '&&ch!=' C ') Ch=getchar ();returnCH;}intMain () {scanf("%d%d", &n,&m); Fo (i,1, N-1){scanf("%d%d", &j,&k); Add (j,k); add (k,j); } DFS (1,0); bz[1]=1; Fo (i,1, m) {ch=get ();scanf("%d", &j);if(ch==' Q ') {ask[i].p=1; Ask[i].x=j; }Else{ask[i].x=j; bz[j]++; }} DG (1,0); FD (I,m,1)if(ASK[I].P) ASK[I].ANS=GETFA (ask[i].x);Else{bz[ask[i].x]--;if(!bz[ask[i].x]) fa[ask[i].x]=father[ask[i].x]; } FO (i,1, m)if(ASK[I].P)printf("%d\n", Ask[i].ans);}
[bzoj4551] [tjoi&heoi2016] Tree