Problem A 腿部挂件
给出$n$个数的序列$a_i$,支持$T$次操作。
每次操作形如$x , l , r$,计算$\max_{i = l}^{r} (a_i \oplus x)$的值。
对于$100\%$的数据满足$1 \leq n \leq 2 \times 10^5 , 0 \leq a_i \leq 10^9$
Solution :
通常可以使用可持久化字典树求解,但是这里可以用字典树套vector来做。
这样当当前节点vector有一个在$l,r$的数中就往下走,还是按照以前的贪心策略,从高位到低位贪心。
这样做的时间复杂度是$O(n {log_2} ^2 n)$
#include<bits/stdc++.h> #define pb push_back using namespace std; struct node { vector<int>p; int ls,rs; node(){ls=rs=-1;} }tr[6100000]; int n,m,a,x,y,cnt,o[50]; void push(int k,int p) { for(int i=30-1,nw=1;i>=0;i--) { if(k&o[i]) { if(tr[nw].ls==-1)tr[nw].ls=++cnt; nw=tr[nw].ls; } else { if(tr[nw].rs==-1)tr[nw].rs=++cnt; nw=tr[nw].rs; } tr[nw].p.pb(p); } } int query(int k,int l,int r) { int ans=0; for(int i=30-1,nw=1;i>=0;i--) { if(k&o[i]) { if(tr[nw].rs==-1||*(tr[tr[nw].rs].p.end()-1)<l||*lower_bound(tr[tr[nw].rs].p.begin(),tr[tr[nw].rs].p.end(),l)>r) nw=tr[nw].ls,ans+=o[i]; else nw=tr[nw].rs; } else { if(tr[nw].ls==-1||*(tr[tr[nw].ls].p.end()-1)<l||*lower_bound(tr[tr[nw].ls].p.begin(),tr[tr[nw].ls].p.end(),l)>r) nw=tr[nw].rs; else nw=tr[nw].ls,ans+=o[i]; } } return ans^k; } int main() { freopen("hugclose.in","r",stdin); freopen("hugclose.out","w",stdout); scanf("%d%d",&n,&m),o[0]=cnt=1; for(int i=1;i<30;i++)o[i]=o[i-1]*2; for(int i=1;i<=n;i++)scanf("%d",&a),push(a,i); for(int i=1;i<=m;i++)scanf("%d%d%d",&a,&x,&y),printf("%d\n",query(a,x+1,y+1)); return 0; }