# bzoj2594: [Wc2006]水管局长数据加强版

Kruskal跑出MST，就可以在树上随便搞；

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
#define mid ((l+r)>>1)
#define LL long long
#define FILE "dealing"
#define up(i,j,n) for(LL i=(j);i<=(n);i++)
#define pii pair<int,int>
int x=0,f=1,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f*x;
}
const int maxn=300010,inf=100000000,mod=998244353;
int n,m,q;
struct edge{int x,y,v;}b[1001000];
bool cmp(edge a,edge b){return a.v<b.v;}
struct node{int y,next,v;}e[2000000],k[2000000];
int ch[maxn],u[maxn],v[maxn];
namespace Kruskal{
int fa[maxn];
int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}
void kruskal(){
cnt_point=n;
bool flag=0;
up(i,1,n)fa[i]=i;
up(i,1,m){
flag=0;
if(k[j].y==b[i].y){
val[k[j].v]=b[i].v;
flag=1;
break;
}
if(k[j].y==b[i].x){
val[k[j].v]=b[i].v;
flag=1;
break;
}
if(flag)continue;
getfa(b[i].x),getfa(b[i].y);
if(fa[b[i].x]==fa[b[i].y])continue;
fa[b[i].x]=fa[b[i].y];
cnt_point++;
f[cnt_point][0]=b[i].x,f[cnt_point][1]=b[i].y;
}
}
};
namespace DFS{
void dfs(int x){
if(e[i].y==fa[x])continue;
if(x>n)w[x]=e[i].v;
Max[x]=x;
fa[e[i].y]=x;
dfs(e[i].y);
}
}
};
namespace LCT{
int c[maxn][2],rev[maxn],q[maxn],top;
void reve(int o){rev[o]^=1,swap(c[o][0],c[o][1]);}
void pushdown(int o){if(rev[o])reve(c[o][0]),reve(c[o][1]),rev[o]^=1;}
void updata(int o){
Max[o]=o;
if(w[Max[c[o][1]]]>w[Max[o]])Max[o]=Max[c[o][1]];
if(w[Max[c[o][0]]]>w[Max[o]])Max[o]=Max[c[o][0]];
}
bool isroot(int o){return c[fa[o]][0]!=o&&c[fa[o]][1]!=o;}
void rotate(int x){
int y=fa[x],z=fa[y],d=(c[y][1]==x);
if(!isroot(y))c[z][c[z][1]==y]=x;
fa[y]=x;fa[x]=z;fa[c[x][d^1]]=y;
c[y][d]=c[x][d^1];c[x][d^1]=y;
updata(y),updata(x);
}
void splay(int x){
q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][1]==x^c[z][1]==y)rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
for(int t=0;x;t=x,x=fa[x])
splay(x),c[x][1]=t,updata(x);
}
void makeroot(int x){
access(x);splay(x);reve(x);
}
void cut(int x,int y){
makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;updata(y);
}
makeroot(x);fa[x]=y;
}
};
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
sort(b+1,b+m+1,cmp);
up(i,1,q)if(ch[i]==2){
}
Kruskal::kruskal();
DFS::dfs(1);
for(int i=q;i>0;i--){
if(ch[i]==1){
LCT::makeroot(x[i]),LCT::access(y[i]),LCT::splay(y[i]);
ans[i]=w[Max[y[i]]];
}
if(ch[i]==2){
LCT::makeroot(x[i]),LCT::access(y[i]),LCT::splay(y[i]);
int t=Max[y[i]];
if(val[i]<w[t]){
LCT::cut(f[t][0],t);LCT::cut(f[t][1],t);
cnt_point++;
f[cnt_point][0]=x[i],f[cnt_point][1]=y[i];
w[cnt_point]=val[i];
}