# 【BZOJ3514】GERALD07加强版（LCT+主席树）

### 前言

$Jan\ 29th$刷题计划（2/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 200000
#define LN 20
#define min(x,y) ((x)<(y)?(x):(y))
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,m;struct line {int x,y;}s[N+5];
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 2*N
#define PU(x) (O[x].Mn=min(O[x].V,min(O[O[x].S[0]].Mn,O[O[x].S[1]].Mn)))
#define PD(x) (O[x].R&&(Re(O[x].S[0]),Re(O[x].S[1]),O[x].R=0))
#define Re(x) (x)&&(swap(O[x].S[0],O[x].S[1]),O[x].R^=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,Mn,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);
}
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);PU(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]) 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=O[i].Mn=m+1;O[0].Mn=m+1;//点的点权设成极大值
for(RI i=1;i<=m;++i) O[n+i].V=O[n+i].Mn=i;//边的点权为边的编号
}
I int Try(CI id)//尝试加入一条新边
{
RI x=s[id].x,y=s[id].y,t=0;FR(x)==FR(y)&&//如果形成了环
(Sp(x,y),t=O[y].Mn,Cut(s[t].x,t+n),Cut(t+n,s[t].y),0);//删去编号最小的边
}
}S;
class ChairmanTree
{
private:
#define LT l,mid,O[rt1].S[0],O[rt2].S[0]
#define RT mid+1,r,O[rt1].S[1],O[rt2].S[1]
int Nt,Rt[N+5];struct node {int V,S[2];}O[N*LN+5];
I void Ins(CI x,CI l,CI r,int& rt1,CI rt2)
{
if(O[rt1=++Nt]=O[rt2],++O[rt1].V,l==r) return;
int mid=l+r>>1;x<=mid?Ins(x,LT):Ins(x,RT);
}
I int Qry(CI x,CI y,CI l,CI r,CI rt1,CI rt2)
{
if(x<=l&&r<=y) return O[rt2].V-O[rt1].V;int mid=l+r>>1;
return (x<=mid?Qry(x,y,LT):0)+(y>mid?Qry(x,y,RT):0);
}
public:
I void Ins(CI v,CI x) {Ins(x,0,m,Rt[v],Rt[v-1]);}//单点修改
I int Qry(CI x,CI y) {return Qry(0,x-1,0,m,Rt[x-1],Rt[y]);}//区间查询
}C;
int main()
{