# 【BZOJ2594】[WC2006] 水管局长数据加强版（重拾LCT）

### 前言

$Jan\ 29th$刷题计划（1/6），算法标签：LCT。

### 代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define M 1000000
#define Pr pair<int,int>
#define mp make_pair
#define max(x,y) ((x)>(y)?(x):(y))
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,m,k,Qt,g[N+5],St[N+5];struct Query {int op,x,y;}q[N+5];
struct edge
{
int x,y,v,p;I edge(CI a=0,CI b=0,CI c=0,CI f=0):x(min(a,b)),y(max(a,b)),v(c),p(f){}//加边时强制x<y
}s[M+5],del[N+5];
I bool cmp_xy(Con edge& x,Con edge& y) {return x.x^y.x?x.x<y.x:x.y<y.y;}//按端点排序
I bool cmp_v(Con edge& x,Con edge& y) {return x.v<y.v;}//按边权排序
I bool cmp_p(Con edge& x,Con edge& y) {return abs(x.p)<abs(y.p);}//按读入顺序排序
class FastIO
{
private:
#define FS 100000
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void writeln(Con Ty& x) {write(x),pc('\n');}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
{
private:
#define SZ N+M
#define PU(x)\
(\
O[x].Mx=O[x].V,O[x].Mp=x,\
O[x].Mx<O[O[x].S[0]].Mx&&(O[x].Mx=O[O[x].S[0]].Mx,O[x].Mp=O[O[x].S[0]].Mp),\
O[x].Mx<O[O[x].S[1]].Mx&&(O[x].Mx=O[O[x].S[1]].Mx,O[x].Mp=O[O[x].S[1]].Mp)\
)
#define PD(x) (O[x].R&&(Re(O[x].S[0]),Re(O[x].S[1]),O[x].R=0))
#define Re(x) (x)&&(O[x].R^=1,swap(O[x].S[0],O[x].S[1]))
#define IR(x) (O[O[x].F].S[0]^(x)&&O[O[x].F].S[1]^(x))
#define Wh(x) (O[O[x].F].S[1]==(x))
#define Co(x,y,d) (O[O[x].F=y].S[d]=x)
#define MR(x) (Ac(x),S(x),Re(x))
#define Sp(x,y) (MR(x),Ac(y),S(y))
int St[SZ+5];struct node {int V,Mx,Mp,R,F,S[2];}O[SZ+5];
I void Ro(int x)
{
RI f=O[x].F,p=O[f].F,d=Wh(x);!IR(f)&&(O[p].S[Wh(f)]=x),
O[x].F=p,Co(O[x].S[d^1],f,d),Co(f,x,d^1),PU(f),PU(x);
}
I void S(int x)
{
RI f=x,T=0;W(St[++T]=f,!IR(f)) f=O[f].F;W(T) PD(St[T]),--T;
W(!IR(x)) f=O[x].F,!IR(f)&&(Ro(Wh(x)^Wh(f)?x:f),0),Ro(x);
}
I void Ac(int x) {for(RI y=0;x;x=O[y=x].F) S(x),O[x].S[1]=y,PU(x);}
I int FR(int x) {Ac(x),S(x);W(O[x].S[0]) PD(x),x=O[x].S[0];return S(x),x;}
I void Link(CI x,CI y) {MR(x),FR(y)^x&&(O[x].F=y);}
I void Cut(CI x,CI y) {MR(x),FR(y)==x&&O[y].F==x&&!O[y].S[0]&&(O[x].S[1]=O[y].F=0,PU(x));}
public:
I void Init() {for(RI i=1;i<=n;++i) O[i].V=-1;for(RI i=1;i<=m;++i) O[n+i].V=s[i].v;}//初始化点权
I void Try(CI id)//加边操作
{
RI x=s[id].x,y=s[id].y,v=s[id].v;if(Sp(x,y),O[y].Mx<s[id].v) return;//如果路径上原最大值比新边权值小，不操作
}
I int Qry(CI x,CI y) {return Sp(x,y),O[y].Mx;}//求树上路径最大值
}S;
namespace MST//求出初始状态下的最小生成树
{
int fa[N+5];I int getfa(CI x) {return fa[x]?fa[x]=getfa(fa[x]):x;}//并查集
I void Work()
{
RI i,fx,fy;for(i=1;i<=m;++i) s[i].p>0&&//s[i].p<0表示这条边被删掉过
}
}
int main()
{
RI i,j,x,y,v,T=0;using namespace MST;