TJOI居然考这么傻逼的题……根JLOI一比真是天壤之别-_-
转成dfs序,然后相当于区间以deep为关键字去max,直接线段树维护就好
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iomanip> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<bitset> using namespace std; #define MAXN 100010 #define MAXM 1010 #define ll long long #define INF 1000000000 #define MOD 1000000007 #define eps 1e-8 struct vec{ int to; int fro; }; vec mp[MAXN]; int tai[MAXN],cnt; int ch[MAXN*4]; int dep[MAXN]; int dfn[MAXN],siz[MAXN],tim; int n,m; inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; } void dfs(int x){ int i,y; siz[x]=1; dfn[x]=++tim; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(!siz[y]){ dep[y]=dep[x]+1; dfs(y); siz[x]+=siz[y]; } } } inline void toch(int x,int y){ if(dep[y]>dep[ch[x]]){ ch[x]=y; } } inline void pd(int x){ if(ch[x]){ toch(x<<1,ch[x]); toch(x<<1|1,ch[x]); ch[x]=0; } } void change(int x,int y,int z,int l,int r,int cv){ if(y==l&&z==r){ toch(x,cv); return ; } pd(x); int mid=y+z>>1; if(r<=mid){ change(x<<1,y,mid,l,r,cv); }else if(l>mid){ change(x<<1|1,mid+1,z,l,r,cv); }else{ change(x<<1,y,mid,l,mid,cv); change(x<<1|1,mid+1,z,mid+1,r,cv); } } int ask(int x,int y,int z,int p){ if(y==z){ return ch[x]; } pd(x); int mid=y+z>>1; if(p<=mid){ return ask(x<<1,y,mid,p); }else{ return ask(x<<1|1,mid+1,z,p); } } int main(){ int i,x,y; char o[2]; scanf("%d%d",&n,&m); for(i=1;i<n;i++){ scanf("%d%d",&x,&y); be(x,y); } dep[1]=1; dfs(1); change(1,1,n,1,n,1); for(i=1;i<=m;i++){ scanf("%s%d",o,&x); if(o[0]=='Q'){ printf("%d\n",ask(1,1,n,dfn[x])); }else{ change(1,1,n,dfn[x],dfn[x]+siz[x]-1,x); } } return 0; } /* 4 4 1 2 2 3 3 4 Q 3 C 2 C 1 Q 3 */