建10棵动态树就完事了~
#include <bits/stdc++.h>
#define N 100004
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int A[N];
map<int,int>pp[N],lk[N];
struct Link_Cut_Tree
{
#define lson t[x].ch[0]
#define rson t[x].ch[1]
int sta[N];
struct Node
{
int ch[2],f,max,val,rev,son;
}t[N];
int isrt(int x)
{
return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x);
}
int get(int x)
{
return t[t[x].f].ch[1]==x;
}
void pushup(int x)
{
if(!x) return;
t[x].max=t[x].val;
if(lson) t[x].max=max(t[x].max, t[lson].max);
if(rson) t[x].max=max(t[x].max, t[rson].max);
}
void mark(int x)
{
if(x) t[x].rev^=1,swap(lson,rson);
}
void pushdown(int x)
{
if(x&&t[x].rev)
{
t[x].rev=0;
if(lson) mark(lson);
if(rson) mark(rson);
}
}
void rotate(int x)
{
int old=t[x].f,fold=t[old].f,which=get(x);
if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x;
t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old;
t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;
pushup(old),pushup(x);
}
void splay(int x)
{
int v=0,u=x,fa;
for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;
for(;v;--v) pushdown(sta[v]);
for(u=t[u].f;(fa=t[x].f)!=u;rotate(x))
if(t[fa].f!=u)
rotate(get(fa)==get(x)?fa:x);
}
void Access(int x)
{
for(int y=0;x;y=x,x=t[x].f)
{
splay(x);
if(rson) t[x].son++;
if(y) t[x].son--;
rson=y;
pushup(x);
}
}
void makeroot(int x)
{
Access(x),splay(x),mark(x);
}
void split(int x,int y)
{
makeroot(x),Access(y),splay(y);
}
void link(int x,int y)
{
makeroot(x),makeroot(y),t[x].f=y,t[y].son++;
}
void cut(int x,int y)
{
makeroot(x),Access(y),splay(y);
t[y].ch[0]=t[x].f=0;
pushup(y);
}
int find(int x)
{
Access(x),splay(x);
for(pushdown(x);lson;pushdown(x)) x=lson;
return x;
}
int check(int x)
{
makeroot(x);
if(t[x].son==0) return 1;
if(t[x].son==1 && !rson) return 1;
return 0;
}
#undef lson
#undef rson
}op[10];
int main()
{
// setIO("input");
int n,m,C,K,i,j;
scanf("%d%d%d%d",&n,&m,&C,&K);
for(i=1;i<=n;++i)
{
scanf("%d",&A[i]);
for(j=0;j<C;++j) op[j].t[i].val=A[i];
}
for(i=1;i<=m;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
op[c].link(a,b);
pp[a][b]=pp[b][a]=c;
lk[a][b]=lk[b][a]=1;
}
for(i=1;i<=K;++i)
{
int opt;
scanf("%d",&opt);
if(opt==0)
{
int x,y;
scanf("%d%d",&x,&y);
for(j=0;j<C;++j) op[j].makeroot(x), op[j].t[x].val=y, op[j].pushup(x);
}
if(opt==1)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(!lk[u][v])
{
printf("No such edge.\n");
}
else
{
int flag2=0,flag1=0;
if(pp[u][v]==w)
{
printf("Success.\n");
}
else if(op[w].find(u)==op[w].find(v))
{
flag2=1;
if(!op[w].check(u) || !op[w].check(v)) flag1=1;
}
else
{
op[w].makeroot(u);
op[w].makeroot(v);
if(op[w].check(u)&&op[w].check(v))
{
op[w].link(u,v);
op[pp[u][v]].cut(u,v);
pp[u][v]=pp[v][u]=w;
printf("Success.\n");
}
else
{
flag1=1;
}
}
if(flag2||flag1)
{
if(flag1) printf("Error 1.\n");
else printf("Error 2.\n");
}
}
}
if(opt==2)
{
int c,u,v;
scanf("%d%d%d",&c,&u,&v);
if(op[c].find(u)!=op[c].find(v)) printf("-1\n");
else
{
op[c].split(u,v);
printf("%d\n",op[c].t[v].max);
}
}
}
return 0;
}