# 【洛谷4585】[FJOI2015] 火星商店问题（线段树分治）

### 代码

#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 max(x,y) ((x)>(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,Et,Qt,ans[N+5];
struct Event {int i,v,t;I bool operator < (Con Event& o) Con {return i<o.i;}}e[N+5];
struct Query {int l,r,v,x,y,t;}q[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;
class ChairmanTrie//可持久化Trie
{
private:
#define ST(x) O[rt1].S[x],O[rt2].S[x],v,d-1
int Nt,Vt,Rt[N+5];struct node {int V,S[2];I void Clear() {V=S[0]=S[1]=0;}}O[N*LN<<2];
I void Ins(CI rt1,int& rt2,CI v,CI d)//插入新数
{
O[rt2=++Nt]=O[rt1],++O[rt2].V;if(!~d) return;int t=(v>>d)&1;Ins(ST(t));
}
I int Qry(CI rt1,CI rt2,CI v,CI d)//求最大异或值
{
if(!rt2||!~d) return 0;int t=(v>>d)&1;
return O[O[rt1].S[t^1]].V^O[O[rt2].S[t^1]].V?Qry(ST(t^1))|(1<<d):Qry(ST(t));
}
public:
I void Insert(CI x) {++Vt,Ins(Rt[Vt-1],Rt[Vt],x,LN);}
I int Query(CI l,CI r,CI x) {return Qry(Rt[l-1],Rt[r],x,LN);}
I void Clear() {W(Nt) Rt[Nt--]=0;W(Vt) O[Vt--].Clear();}//清空
}C;
class SegmentTree
{
private:
#define PT CI l=1,CI r=Et,CI rt=1
#define LT l,mid,rt<<1
#define RT mid+1,r,rt<<1|1
#define pb push_back
int s[N+5];Event tl[N+5],tr[N+5];vector<int> P[N<<2];
public:
I void Ins(CI x,CI y,CI p,PT)//扔入询问
{
if(x<=l&&r<=y) return P[rt].pb(p);int mid=l+r>>1;//开vector存储一个节点上的询问
x<=mid&&(Ins(x,y,p,LT),0),y>mid&&(Ins(x,y,p,RT),0);
}
I void Solve(CI x,CI y,PT)//二分求答案
{
if(x>y) return;RI i,t,t1,t2,k=0;int mid=l+r>>1;vector<int>::iterator it;
for(C.Clear(),i=x;i<=y;++i) s[++k]=e[i].i,C.Insert(e[i].v);//将修改对应到可持久化Trie树上
for(it=P[rt].begin();it!=P[rt].end();++it)//枚举这个节点上的询问
t1=upper_bound(s+1,s+k+1,q[*it].l-1)-s,t2=upper_bound(s+1,s+k+1,q[*it].r)-s-1,//求出询问在可持久化Trie树上对应的区间
t=C.Query(t1,t2,q[*it].v),Gmax(ans[q[*it].t],t);//在可持久化Trie树上询问，更新答案
if(l==r) return;for(t1=t2=0,i=x;i<=y;++i) e[i].t<=mid?tl[++t1]=e[i]:tr[++t2]=e[i];
for(i=1;i<=t1;++i) e[x+i-1]=tl[i];for(i=1;i<=t2;++i) e[x+i+t1-1]=tr[i];
Solve(x,x+t1-1,LT),Solve(x+t1,y,RT);//递归操作
}
}S;
int main()
{