P4092 [HEOI2016/TJOI2016]树
树链剖分+线段树
#include<bits/stdc++.h>
//#define int long long
#define pb push_back
#define memarray(array, value) memset(array, value, sizeof(array))
using namespace std;
const double EPS=1e-5;
const double PI=acos(-1);
const long long mod=998244353;
const int INF=0x3f3f3f3f;
inline int sgn(double a){ return a < -EPS ? -1 : a > EPS; }
inline int cmp(double a, double b){ return sgn(a-b); }
inline int gcd(int x,int y){if(y==0)return x;return gcd(y,x%y);}
const int MAXN=1e5+10;
const int N=35;
int n,m;
vector<int>vec[MAXN];
int son[MAXN];
int fa[MAXN];
int depth[MAXN];
int bigson[MAXN];
void dfs1(int now,int pre){
son[now]=1;
int bigsonnum=-1;
for(auto to:vec[now]){
if(to==pre)continue;
depth[to]=depth[now]+1;
fa[to]=now;
dfs1(to,now);
son[now]+=son[to];
if(son[to]>bigsonnum){
bigson[now]=to;
bigsonnum=son[to];
}
}
}
int dfn[MAXN],top[MAXN],pos[MAXN];
int cuo;
void dfs2(int now,int tp){
dfn[now]=++cuo;
pos[cuo]=now;
top[now]=tp;
if(!bigson[now])return;
dfs2(bigson[now],tp);
for(auto to:vec[now]){
if(to!=fa[now]&&to!=bigson[now])
dfs2(to,to);
}
}
int val[MAXN<<2];
void pushup(int rt){
val[rt]=val[rt<<1]+val[rt<<1|1];
}
void Insert(int l,int r,int rt,int pos,int v){
if(l==r){
val[rt]=v;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)Insert(l,mid,rt<<1,pos,v);
else Insert(mid+1,r,rt<<1|1,pos,v);
pushup(rt);
}
int Q(int l,int r,int rt){
if(l==r){
if(val[rt])
return l;
return 0;
}
int mid=(l+r)>>1;
int ans=0;
if(val[rt<<1|1])ans=max(ans,Q(mid+1,r,rt<<1|1));
else if(val[rt<<1]) ans=max(ans,Q(l,mid,rt<<1));
return ans;
}
int Tree_Q(int l,int r,int rt,int L,int R){
if(L<=l&&r<=R){
if(val[rt])
return Q(l,r,rt);
return 0;
}
int mid=(l+r)>>1;
int ans=0;
if(L<=mid) ans=max(ans,Tree_Q(l,mid,rt<<1,L,R));
if(R>mid) ans=max(ans,Tree_Q(mid+1,r,rt<<1|1,L,R));
return ans;
}
int Quary(int x){
while(top[x]!=1){
int tmp=Tree_Q(1,n,1,dfn[top[x]],dfn[x]);
if(tmp)return pos[tmp];
x=fa[top[x]];
}
int tmp=Tree_Q(1,n,1,dfn[1],dfn[x]);
return pos[tmp];
}
bool tag[MAXN];
void solve(){
depth[1]=1;
dfs1(1,0);
dfs2(1,1);
tag[1]=1;
Insert(1,n,1,1,1);
char op[3];
int id;
while(m--){
scanf("%s%d",op,&id);
if(op[0]=='Q'){
printf("%d\n",Quary(id));
}else{
if(tag[id])continue;
Insert(1,n,1,dfn[id],1);
tag[id]=true;
}
}
}
void init(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
vec[u].pb(v);
vec[v].pb(u);
}
}
signed main(){
int T;
// scanf("%d",&T);
T=1;
// while(T--){
for(int i=1;i<=T;i++){
init();
solve();
}
return 0;
}