传送门
同BZOJ3083
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int max_n=1e5+5;
const int max_e=max_n;
const int max_tree=max_n*4;
const int INF=2147483647;
int n,m,N,fa,root,x,y;
int tot,point[max_n],next[max_e],v[max_e];
int a[max_n],father[max_n],in[max_n],out[max_n],val[max_n];
int tree[max_tree];
inline void addedge(int x,int y){++tot;next[tot]=point[x];point[x]=tot;v[tot]=y;}
inline void dfs(int x,int fa){
father[x]=fa; in[x]=++N; val[N]=a[x];
for (int i=point[x];i;i=next[i])
if (v[i]!=fa)
dfs(v[i],x);
out[x]=N;
}
inline void update(int now){
tree[now]=min(tree[now<<1],tree[now<<1|1]);
}
inline void build(int now,int l,int r){
int mid=(l+r)>>1;
if (l==r){
tree[now]=val[l];
return;
}
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
update(now);
}
inline void point_change(int now,int l,int r,int x,int v){
int mid=(l+r)>>1;
if (l==r){
tree[now]=v;
return;
}
if (x<=mid) point_change(now<<1,l,mid,x,v);
else point_change(now<<1|1,mid+1,r,x,v);
update(now);
}
inline int query(int now,int l,int r,int lrange,int rrange){
int mid=(l+r)>>1,ans=INF;
if (lrange<=l&&r<=rrange) return tree[now];
if (lrange<=mid) ans=min(ans,query(now<<1,l,mid,lrange,rrange));
if (mid+1<=rrange) ans=min(ans,query(now<<1|1,mid+1,r,lrange,rrange));
return ans;
}
inline int ask(int x){
if (root==x) return query(1,1,N,1,N);
if (!(in[root]>=in[x]&&in[root]<=out[x])) return query(1,1,N,in[x],out[x]);
int ans=INF;
for (int i=point[x];i;i=next[i])
if (v[i]!=father[x]&&in[root]>=in[v[i]]&&in[root]<=out[v[i]]){
if (1<=in[v[i]]-1) ans=min(ans,query(1,1,N,1,in[v[i]]-1));
if (out[v[i]]+1<=N) ans=min(ans,query(1,1,N,out[v[i]]+1,N));
break;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i){
scanf("%d%d",&fa,&a[i]);
if (fa) addedge(fa,i);
else root=i;
}
dfs(root,0);
build(1,1,N);
for (int i=1;i<=m;++i){
char opt=getchar();
while (opt!='V'&&opt!='E'&&opt!='Q') opt=getchar();
if (opt=='V'){
scanf("%d%d",&x,&y);
point_change(1,1,N,in[x],y);
}
if (opt=='E'){
scanf("%d",&x);
root=x;
}
if (opt=='Q'){
scanf("%d",&x);
int ans=ask(x);
printf("%d\n",ans);
}
}
}
手写栈
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int max_n=1e5+5;
const int max_e=max_n;
const int max_tree=max_n*4;
const int INF=2147483647;
int n,m,N,fa,root,x,y;
int tot,point[max_n],next[max_e],v[max_e];
int a[max_n],father[max_n],in[max_n],out[max_n],val[max_n];
int tree[max_tree];
int cur[max_n],strack[max_n];
inline void addedge(int x,int y){++tot;next[tot]=point[x];point[x]=tot;v[tot]=y;}
inline void dfs()
{
int temp=0;
in[root]=++N; val[N]=a[root];
strack[++temp]=root;
for (int i=1;i<=n;++i) cur[i]=point[i];
while (temp)
{
int x=strack[temp];
if (v[cur[x]]==father[x])
cur[x]=next[cur[x]];
if (!cur[x])
{
out[strack[temp]]=N;
--temp;
continue;
}
int vt=v[cur[x]];
strack[++temp]=vt; father[vt]=x;
in[vt]=++N; val[N]=a[vt];
cur[x]=next[cur[x]];
}
}
inline void update(int now){
tree[now]=min(tree[now<<1],tree[now<<1|1]);
}
inline void build(int now,int l,int r){
int mid=(l+r)>>1;
if (l==r){
tree[now]=val[l];
return;
}
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
update(now);
}
inline void point_change(int now,int l,int r,int x,int v){
int mid=(l+r)>>1;
if (l==r){
tree[now]=v;
return;
}
if (x<=mid) point_change(now<<1,l,mid,x,v);
else point_change(now<<1|1,mid+1,r,x,v);
update(now);
}
inline int query(int now,int l,int r,int lrange,int rrange){
int mid=(l+r)>>1,ans=INF;
if (lrange<=l&&r<=rrange) return tree[now];
if (lrange<=mid) ans=min(ans,query(now<<1,l,mid,lrange,rrange));
if (mid+1<=rrange) ans=min(ans,query(now<<1|1,mid+1,r,lrange,rrange));
return ans;
}
inline int ask(int x){
if (root==x) return query(1,1,N,1,N);
if (!(in[root]>=in[x]&&in[root]<=out[x])) return query(1,1,N,in[x],out[x]);
int ans=INF;
for (int i=point[x];i;i=next[i])
if (v[i]!=father[x]&&in[root]>=in[v[i]]&&in[root]<=out[v[i]]){
if (1<=in[v[i]]-1) ans=min(ans,query(1,1,N,1,in[v[i]]-1));
if (out[v[i]]+1<=N) ans=min(ans,query(1,1,N,out[v[i]]+1,N));
break;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i){
scanf("%d%d",&fa,&a[i]);
if (fa) addedge(fa,i);
else root=i;
}
dfs();
build(1,1,N);
for (int i=1;i<=m;++i){
char opt=getchar();
while (opt!='V'&&opt!='E'&&opt!='Q') opt=getchar();
if (opt=='V'){
scanf("%d%d",&x,&y);
point_change(1,1,N,in[x],y);
}
if (opt=='E'){
scanf("%d",&x);
root=x;
}
if (opt=='Q'){
scanf("%d",&x);
int ans=ask(x);
printf("%d\n",ans);
}
}
}
1A嘿嘿嘿