这个题我做的时候没有考虑到一个性质,导致多了一个log,然后麻烦了好多好多。
就是说合并两个区间的时候,我以为左边的最小值会接管右边第一个比它小的左边的一段,所以我要求这一段的最大值。
但是实际上,如果右边右段的最大值比右边左段的最大值大的话,显然这是无论如何都不能更新答案的,所以我们直接用右边的最大值就好了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
#include<algorithm>
#include<cstdlib>
#define inf 1e9
//About read
inline void in(int &x){
char c=getchar();
while(c<'0'||c>'9')c=getchar();
x=0;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
}
int a[200005];
//About tree
int ptr[100005],next[200005],succ[200005],etot=1;
int fa[200005][18],son[200005][18];//[i,i+2^j)
int depth[200005];
struct TS{
int max,min,ans,revans;
}st[200005][18];
inline void addedge(int u,int v){
next[etot]=ptr[u],ptr[u]=etot,succ[etot++]=v;
}
inline TS merge(TS a,TS b){
return (TS){max(a.max,b.max),min(a.min,b.min),max(b.max-a.min,max(a.ans,b.ans)),max(a.max-b.min,max(a.revans,b.revans))};
}
inline void out(TS a){
cout<<"{"<<a.max<<","<<a.min<<","<<a.ans<<","<<a.revans<<"}";
}
inline void build(int node){
depth[node]=depth[fa[node][1]]+1;
fa[node][0]=node;
for(int i=2;i<18;++i)fa[node][i]=fa[fa[node][i-1]][i-1];
st[node][0]=(TS){a[node],a[node],0};
st[node][1]=(TS){max(a[fa[node][1]],a[node]),min(a[fa[node][1]],a[node]),max(a[fa[node][1]]-a[node],0),max(a[node]-a[fa[node][1]],0)};
for(int i=2;i<18;++i){
st[node][i]=merge(st[node][i-1],st[fa[node][i-1]][i-1]);
/*cout<<"Merge:";
out(st[node][i-1]);
cout<<"+";
out(st[fa[node][i-1]][i-1]);
cout<<"=";
out(st[node][i]);
cout<<endl;*/
}
for(int i=ptr[node];i;i=next[i])
if(succ[i]!=fa[node][1]){
fa[succ[i]][1]=node;
build(succ[i]);
}
}
int main(){
freopen("lct.in","r",stdin);
freopen("lct.out","w",stdout);
int n,m,i,j,u,v,s,t,type;
in(n);
for(i=1;i<=n;++i)in(a[i]);
for(i=n;--i;){
in(u),in(v);
addedge(u,v),addedge(v,u);
}
build(1);
/*for(i=1;i<=n;++i){
cout<<"----"<<i<<"-----\n";
for(j=0;j<18&&fa[i][j];++j){
cout<<fa[i][j]<<":";
out(st[i][j]);
cout<<endl;
}
}*/
in(m);
int lastans=0,cha;
TS ans,revans;
while(m--){
in(type);
if(type==1){
in(s),in(t);
s^=lastans,t^=lastans;
revans=st[t][0],ans=st[s][0],cha=abs(depth[s]-depth[t]);
if(depth[s]>depth[t])//把s往上调
for(i=18;--i;)
if(depth[fa[s][i]]>=depth[t]){
ans=merge(ans,st[s][i]);
s=fa[s][i];
}
if(depth[s]<depth[t])//把t往上调
for(i=18;--i;)
if(depth[fa[t][i]]>=depth[s]){
revans=merge(revans,st[t][i]);
t=fa[t][i];
}
if(s!=t){
for(i=18;--i;)
if(fa[s][i]!=fa[t][i]){
ans=merge(ans,st[s][i]),revans=merge(revans,st[t][i]);
s=fa[s][i],t=fa[t][i];
}
ans=merge(ans,st[s][1]);
}
lastans=max(revans.max-ans.min,max(ans.ans,revans.revans));
printf("%d\n",lastans);
}
else{
in(a[++n]),in(fa[n][1]);
fa[n][1]^=lastans;
fa[n][0]=n;
depth[n]=depth[fa[n][1]]+1;
for(i=2;i<18;++i)fa[n][i]=fa[fa[n][i-1]][i-1];
st[n][0]=(TS){a[n],a[n],0};
st[n][1]=(TS){max(a[n],a[fa[n][1]]),min(a[n],a[fa[n][1]]),max(a[fa[n][1]]-a[n],0),max(a[n]-a[fa[n][1]],0)};
for(i=2;i<18;++i)st[n][i]=merge(st[n][i-1],st[fa[n][i-1]][i-1]);
}
}
}