水水的splay 准确说是splay森林
其实不止颜色数的splay树 (还有一些单点也可以存在)
不过都可以用 一个 [C][N] 存下来
其实splay之间的边 都不是实际上连起来的边
每个点其实实际上是和它的前驱后继连起来的
不然zigzag就会破坏结果 原因自行脑补
还有要注意有时候需要一个reverse
要连接的两条链 需要 一个的 节点 的d 儿子
另一个节点的 d ^ 1 儿子
均为空 即等于0
才可以连接 否则为非法情况
剩下的就靠码力了
拒绝眼残 拒绝手残。。
就好了
#include <cstdio>
#include <map>
#define lp(i,j,k) for(int i = j;i <= k;++i)
#define CH(i,j,k) ch[i][j][k]
#define FA(i,j) fa[i][j]
#define D 10010
using namespace std;
map<pair<int,int>,int>MAP;
int a[D],n,m,c,k,u,v,w,fa[11][D],x[11][D],ch[11][D][2];
bool lazy[11][D];
void reverse (int col,int X) {
int temp = CH(col,X,1);
CH(col,X,1) = CH(col,X,0);
CH(col,X,0) = temp;
if(X)
lazy[col][X] ^= 1;
}
void push_down (int col,int X) {
if(lazy[col][X]) {
reverse(col,CH(col,X,0));
reverse(col,CH(col,X,1));
}
lazy[col][X] = 0;
}
void push_up (int col,int X) {
x[col][X] = max(x[col][CH(col,X,0)],x[col][CH(col,X,1)]);
x[col][X] = max(x[col][X],a[X]);
}
void rot (int col,int X,int d) {
x[col][X] = x[col][FA(col,X)];
x[col][FA(col,X)] = max(x[col][CH(col,X,d)],a[FA(col,X)]);
x[col][FA(col,X)] = max(x[col][FA(col,X)],x[col][CH(col,FA(col,X),d)]);
CH(col,FA(col,X),d ^ 1) = CH(col,X,d);
if(CH(col,X,d))
FA(col,CH(col,X,d)) = FA(col,X);
CH(col,X,d) = FA(col,X);
int temp = FA(col,FA(col,X));
FA(col,FA(col,X)) = X;
FA(col,X) = temp;
if(!temp)
return;
if(CH(col,temp,1) == CH(col,X,d))
CH(col,temp,1) = X;
else CH(col,temp,0) = X;
}
void splay (int col,int X) {
while(FA(col,X)) {
if(FA(col,FA(col,X))) {
push_down(col,FA(col,FA(col,X)));
push_down(col,FA(col,X));
push_down(col,X);
int d = CH(col,FA(col,FA(col,X)),0) == FA(col,X);
if(CH(col,FA(col,X),d) == X)
rot(col,X,d ^ 1),rot(col,X,d);
else rot(col,X,d),rot(col,X,d);
}
else {
push_down(col,FA(col,X));
push_down(col,X);
if(CH(col,FA(col,X),1) == X)
rot(col,X,0);
else rot(col,X,1);
}
}
}
int main () {
scanf("%d%d%d%d",&n,&m,&c,&k);
lp(i,1,n) {
scanf("%d",&a[i]);
lp(j,1,c)
x[j][i] = a[i];
}
lp(i,1,m) {
scanf("%d%d%d",&u,&v,&w);
++w;
MAP[make_pair(u,v)] = w;
MAP[make_pair(v,u)] = w;
splay(w,v);
splay(w,u);
int d;
if(CH(w,u,0))
d = 1;
else d = 0;
if(CH(w,v,d ^ 1))
reverse(w,v);
CH(w,u,d) = v;
FA(w,v) = u;
push_up(w,u);
splay(w,v);
}
lp(i,1,k) {
scanf("%d",&w);
if(w == 0) {
scanf("%d%d",&u,&v);
a[u] = v;
lp(j,1,c) {
splay(j,u);
x[j][u] = max(x[j][u],v);
}
}
else {
if(w == 1) {
scanf("%d%d%d",&u,&v,&w);
++w;
int col = MAP[make_pair(u,v)];
if(!col)
printf("No such edge.\n");
else {
if(col == w) {
printf("Success.\n");
continue;
}
else {
splay(w,u);
splay(w,v);
if((CH(w,u,0) && CH(w,u,1)) || (CH(w,v,0) && CH(w,v,1))) {
printf("Error 1.\n");
continue;
}
bool f = 0;
lp(hh,0,1) {
if(CH(w,v,hh) == u && CH(w,v,hh ^ 1) == 0) {
f = printf("Error 2.\n"),1;
break;
}
}
if(f)
continue;
splay(col,u);
splay(col,v);
int d;
if(CH(col,v,0) == u)
CH(col,v,0) = 0;
else CH(col,v,1) = 0;
FA(col,u) = 0;
push_up(col,u);
push_up(col,v);
if(CH(w,u,0))
d = 1;
else d = 0;
if(CH(w,v,d ^ 1))
reverse(w,v);
CH(w,u,d) = v;
FA(w,v) = u;
push_up(w,u);
MAP[make_pair(u,v)] = w;
MAP[make_pair(v,u)] = w;
printf("Success.\n");
}
}
}
else {
scanf("%d%d%d",&w,&u,&v);
++w;
splay(w,u);
splay(w,v);
int d = CH(w,v,1) == u;
if(v != u) {
if(d) {
int pr = max(x[w][CH(w,u,0)],a[v]);
pr = max(pr,a[u]);
printf("%d\n",pr);
}
else {
if(CH(w,v,0) == u) {
int pr = max(x[w][CH(w,u,1)],a[v]);
pr = max(pr,a[u]);
printf("%d\n",pr);
}
else printf("-1\n");
}
}
else printf("%d\n",a[u]);
}
}
}
}