无语了……
参考hzwer的题解,我自己没想出来……
具体就是先搞一遍LCA,再分三种情况判断
详见hzwer题解:传送门
判定ROOT时居然写了if(ROOT=x)简直爆炸
没救了
#include<cstdio>
#include<algorithm>
using namespace std;
int h[100005],en,fa[100005][18],data[100005],dfn,L[100005],R[100005],pre[100005],ROOT=1,bits[20],dep[100005],n,q;
struct Edge{
int b,next;
}e[200005];
struct SegTree{
int l,r,mn;
}tree[400005];
void Pushup(int root){
tree[root].mn=min(tree[root*2].mn,tree[root*2+1].mn);
}
void Build(int root,int l,int r){
tree[root].l=l;
tree[root].r=r;
if(l==r){
tree[root].mn=data[pre[l]];
return;
}
int mid=l+r>>1;
Build(root*2,l,mid);
Build(root*2+1,mid+1,r);
Pushup(root);
}
void Change(int root,int pos,int val){
if(tree[root].l==tree[root].r){
tree[root].mn=val;
return;
}
int mid=tree[root].l+tree[root].r>>1;
if(pos<=mid)Change(root*2,pos,val);
if(pos>mid)Change(root*2+1,pos,val);
Pushup(root);
}
int GtMn(int root,int l,int r){
if(l>r)return 2100000000;
if(tree[root].l>=l && tree[root].r<=r){
return tree[root].mn;
}
int mid=tree[root].l+tree[root].r>>1,ans=2100000000;
if(l<=mid)ans=min(ans,GtMn(root*2,l,r));
if(r>mid)ans=min(ans,GtMn(root*2+1,l,r));
return ans;
}
void AddEdge(int sa,int sb){
e[++en].b=sb;
e[en].next=h[sa];
h[sa]=en;
}
void dfs(int u){
L[u]=++dfn;
pre[dfn]=u;
for(int i=1;i<=18;i++){
if(bits[i]<=dep[u])fa[u][i]=fa[fa[u][i-1]][i-1];
else break;
}
for(int i=h[u];i;i=e[i].next){
int v=e[i].b;
dep[v]=dep[u]+1;
fa[v][0]=u;
dfs(v);
}
R[u]=dfn;
}
int main(){
freopen("3306.in","r",stdin);
freopen("3306.out","w",stdout);
bits[0]=1;
for(int i=1;i<=18;i++)bits[i]=bits[i-1]<<1;
scanf("%d %d",&n,&q);
//printf("%d %d\n",n,q);
for(int i=1;i<=n;i++){
int u;
scanf("%d %d",&u,&data[i]);
//printf("%d %d\n",u,data[i]);
if(u)AddEdge(u,i);
}
dfs(ROOT=1);
Build(1,1,n);
for(int i=1;i<=q;i++){
char s[5];
int x,y;
scanf("%s",s);
if(s[0]=='V'){
scanf("%d %d",&x,&y);
Change(1,L[x],y);
}
if(s[0]=='E'){
scanf("%d",&x);
ROOT=x;
}
if(s[0]=='Q'){
scanf("%d",&x);
if(ROOT==x){printf("%d\n",tree[1].mn);continue;}
if(L[x]<=L[ROOT] && R[x]>=R[ROOT]){
y=ROOT;
int deep=dep[y]-dep[x]-1;
for(int i=0;i<=18;i++){
if(bits[i]&deep)y=fa[y][i];
}
printf("%d\n",min(GtMn(1,1,L[y]-1),GtMn(1,R[y]+1,n)));
continue;
}
printf("%d\n",GtMn(1,L[x],R[x]));
}
}
return 0;
}
评论 (0)