又看了一下LCT,复杂度还是不懂,怎么样均摊O(longn)???感觉一写残就退化了。。。
于是回顾了一下板子,总算是过了。。原树上的父亲大概是没有记吧。。
不知道为什么find改成这样会T。。TAT
int find(int x)
{
acc(x);splay(x);
while(c[x][0])x=c[x][0];
return x;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 150005
using namespace std;
int n,m,a[N],Fa[N];
int read()
{
int x=0,f=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
return x*f;
}
int GetFa(int x){return Fa[x]==x?x:Fa[x]=GetFa(Fa[x]);}
struct LCT
{
int c[N][2],fa[N],p[N];
int v[N],sum[N];
bool rev[N];
int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
bool Root(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void up(int x)
{
int l=c[x][0],r=c[x][1];
sum[x]=v[x]+sum[l]+sum[r];
}
void down(int x)
{
if (!x||!rev[x]) return;
rev[c[x][0]]^=1,rev[c[x][1]]^=1;
swap(c[x][0],c[x][1]);rev[x]=0;
}
void pushdown(int x){if(!Root(x))pushdown(fa[x]);down(x);}
void rotate(int x)
{
int y=fa[x],z=fa[y],l=(c[y][0]!=x),r=l^1;
if (!Root(y)){if (c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;up(y);up(x);
}
void splay(int x)
{
for (pushdown(x);!Root(x);rotate(x))
{
int y=fa[x],z=fa[y];
if (!Root(y))
{if (c[y][0]==x^c[z][0]==y)rotate(x);else rotate(y);}
}
}
void acc(int x){for(int t=0;x;t=x,x=GetFa(fa[x]))splay(x),c[x][1]=t,fa[t]=x,up(x);}
void MRt(int x){acc(x);splay(x);rev[x]^=1;}
void link(int x,int y){MRt(x);fa[x]=y;p[find(x)]=y;}
void mdy(int x,int y){splay(x);v[x]+=y;up(x);}
int qry(int x,int y){MRt(x);acc(y);splay(y);return sum[y];}
void bing(int x,int y)
{
down(x);Fa[x]=y;
if (x!=y) v[y]+=v[x];
if (c[x][0]) bing(c[x][0],y);
if (c[x][1]) bing(c[x][1],y);
c[x][0]=c[x][1]=0;
}
void add(int x,int y)
{
x=GetFa(x),y=GetFa(y);
if (x!=y)
{
if (find(x)==find(y))
MRt(x),acc(y),splay(y),bing(y,y);
else link(x,y);
}
}
}T;
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++)
a[i]=read(),T.mdy(i,a[i]),Fa[i]=i,T.p[i]=i;
while(m--)
{
int p=read(),x=read(),y=read();
switch(p)
{
case 1:T.add(x,y);break;
case 2:T.mdy(GetFa(x),y-a[x]);a[x]=y;break;
case 3:x=GetFa(x);y=GetFa(y);
if(T.find(x)==T.find(y))
printf("%d\n",T.qry(x,y));
else puts("-1");break;
}
}
return 0;
}