# 【BZOJ4771】七彩树（主席树）

### 代码

#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 LN 20
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,d,ee,a[N+5],fa[N+5][LN+1],dep[N+5],dI[N+5],dO[N+5],D[N+5],lnk[N+5];
struct data {int p,d;I bool operator < (Con data& o) Con {return d<o.d;}}t[N+5];
struct edge {int to,nxt;}e[N];set<int> s[N+5];set<int>::iterator it;
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;}
#undef D
}F;
class ChairmanTree//主席树
{
private:
#define L l,mid,O[rt].S[0]
#define R mid+1,r,O[rt].S[1]
#define PU(x) (O[x].V=O[O[x].S[0]].V+O[O[x].S[1]].V)
int tot,Rt[N+5];struct node {int V,S[2];}O[N*LN<<2];
I void ins(CI l,CI r,int& rt,RI lst,CI x,CI t)//插入
{
if(O[rt=++tot]=O[lst],l==r) return (void)(O[rt].V+=t);RI mid=(l+r)/2;
x<=mid?ins(L,O[lst].S[0],x,t):ins(R,O[lst].S[1],x,t),PU(rt);
}
I int qry(CI l,CI r,CI rt,CI tl,CI tr)//询问
{
if(!rt||(tl<=l&&r<=tr)) return O[rt].V;RI mid=(l+r)/2;
return (tl<=mid?qry(L,tl,tr):0)+(tr>mid?qry(R,tl,tr):0);
}
public:
I void Clear() {tot=0,memset(Rt,0,sizeof(Rt));}//清空
I void Insert(CI v,CI ov,CI x,CI t) {ins(1,n,Rt[v],Rt[ov],x,t);}
I int Query(CI v,CI l,CI r) {return qry(1,n,Rt[v],l,r);}
}C;
I void dfs(CI x)//dfs遍历预处理LCA和dfs序
{
RI i;for(D[dI[x]=++d]=x,i=1;i<=LN;++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for(i=lnk[x];i;i=e[i].nxt) dfs(e[i].to);dO[x]=d;
}
I int LCA(RI x,RI y)//倍增求LCA
{
RI i;for(dep[x]<dep[y]&&swap(x,y),i=0;dep[x]^dep[y];++i) (dep[x]^dep[y])>>i&1&&(x=fa[x][i]);
if(x==y) return x;for(i=LN;~i;--i) fa[x][i]^fa[y][i]&&(x=fa[x][i],y=fa[y][i]);return fa[x][0];
}
int main()
{
{