lct维护最小生成树裸题
(神tm加强版 按照原版写的一直t 原来数组开小了=.=
#include <cstdio>
#include <algorithm>
using namespace std;
int ch[300010][2],fa[300010],rv[300010],x[300010],ans[300010],ans_o[300010];
int cnt,ccnt;
int st[300010],tp;
int head[100010];
int f[100010],U[100010],V[100010],W[100010],n,m,q,pr[100010];
struct edge {
int u,v,w;
bool operator < (const edge &b)const {
return w < b.w;
}
}e[1000010];
int UU[1000010],VV[1000010];
inline bool cmp (const edge &a,const edge &b) {
if(a.u == b.u)
return a.v < b.v;
return a.u < b.u;
}
inline int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0'; c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}
inline int find (int u) {
if(head[u] == u)
return u;
return head[u] = find(head[u]);
}
inline void pu (int u) {
ans[u] = x[u];
ans_o[u] = u;
if(ans[ch[u][1]] > ans[u]) {
ans[u] = ans[ch[u][1]];
ans_o[u] = ans_o[ch[u][1]];
}
if(ans[ch[u][0]] > ans[u]) {
ans[u] = ans[ch[u][0]];
ans_o[u] = ans_o[ch[u][0]];
}
}
inline void rot (int u,int d) {
ch[fa[u]][d ^ 1] = ch[u][d];
if(ch[u][d])
fa[ch[u][d]] = fa[u];
int t = fa[fa[u]];
ch[u][d] = fa[u];
fa[fa[u]] = u;
fa[u] = t;
pu(ch[u][d]);
pu(u);
if(!t)
return;
if(ch[t][0] == ch[u][d])
ch[t][0] = u;
if(ch[t][1] == ch[u][d])
ch[t][1] = u;
}
inline void reverse (int u) {
int t = ch[u][0];
ch[u][0] = ch[u][1];
ch[u][1] = t;
rv[u] ^= 1;
}
inline void pd (int u) {
if(!rv[u])
return;
rv[u] = 0;
reverse(ch[u][0]);
reverse(ch[u][1]);
}
inline void splay (int u) {
int t = u;
st[tp = 1] = t;
while(ch[fa[t]][0] == t || ch[fa[t]][1] == t) {
t = fa[t];
st[++tp] = t;
}
while(tp)
pd(st[tp--]);
while(ch[fa[u]][0] == u || ch[fa[u]][1] == u) {
if(ch[fa[fa[u]]][0] != fa[u] && ch[fa[fa[u]]][1] != fa[u]) {
if(ch[fa[u]][0] == u)
rot(u,1);
else rot(u,0);
}
else {
int d = ch[fa[fa[u]]][0] == fa[u];
if(ch[fa[u]][d] == u) {
rot(u,d ^ 1);
rot(u,d);
}
else {
rot(u,d);
rot(u,d);
}
}
}
}
inline void access (int u) {
int v = 0;
while(u) {
splay(u);
ch[u][1] = v;
pu(u);
v = u;
u = fa[u];
}
}
inline void mtr (int u) {
access(u);
splay(u);
reverse(u);
}
inline void link (int u,int v) {
mtr(u);
mtr(v);
fa[u] = v;
}
inline int find_v (int u,int d) {
if(ch[u][d ^ 1]) {
u = ch[u][d ^ 1];
while(ch[u][d])
u = ch[u][d];
}
return u;
}
inline void cut (int u,int v) {
mtr(v);
access(v);
splay(u);
fa[u] = 0;
}
int main () {
n = read_int();
m = read_int();
q = read_int();
for(int i = 1;i <= n;++i) {
ans_o[i] = i;
head[i] = i;
}
for(int i = 1;i <= m;++i) {
e[i].u = read_int();
e[i].v = read_int();
e[i].w = read_int();
if(e[i].u > e[i].v) {
int t = e[i].u;
e[i].u = e[i].v;
e[i].v = t;
}
}
sort(e + 1,e + 1 + m,cmp);
for(int i = 1;i <= m;++i) {
UU[i] = e[i].u;
VV[i] = e[i].v;
}
for(int i = 1;i <= q;++i) {
f[i] = read_int();
U[i] = read_int();
V[i] = read_int();
if(f[i] == 2) {
int u = min(U[i],V[i]);
int v = max(U[i],V[i]);
int lo = lower_bound(UU + 1,UU + 1 + m,u) - UU;
int up = upper_bound(UU + 1,UU + 1 + m,u) - UU;
int t = lower_bound(VV + lo,VV + up,v) - VV;
W[i] = e[t].w;
e[t].w = 0x3f3f3f3f;
}
}
sort(e + 1,e + 1 + m);
ccnt = n;
for(int i = 1;i <= n - 1;++i) {
while(find(e[++cnt].u) == find(e[cnt].v));
head[find(e[cnt].u)] = find(e[cnt].v);
x[++ccnt] = ans[ccnt] = e[cnt].w;
ans_o[ccnt] = ccnt;
link(ccnt,e[cnt].u);
link(ccnt,e[cnt].v);
}
for(int i = q;i >= 1;--i) {
mtr(U[i]);
access(V[i]);
splay(U[i]);
if(f[i] == 1)
pr[i] = ans[U[i]];
else {
if(ans[U[i]] > W[i]) {
int t = ans_o[U[i]];
splay(t);
int u = find_v(t,1);
int v = find_v(t,0);
cut(u,t);
cut(v,t);
x[++ccnt] = ans[ccnt] = W[i];
ans_o[ccnt] = ccnt;
link(ccnt,U[i]);
link(ccnt,V[i]);
}
}
}
for(int i = 1;i <= q;++i) {
if(pr[i])
printf("%d\n",pr[i]);
}
}