题意:
给定长度为n的序列a,q次询问,
每次询问给定x,l,r,要求计算a[l,r]中的数,与x的最大异或值是多少,输出最大异或值。
数据范围:n<=1e5,a(i),b(i)<=1e9
解法:
找最大异或值一般用字典树做,
找区间中最大的异或值就是对区间建立字典树,
那么对字典树进行可持久化处理即可.
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e5+5;
int rt[maxm],tot;
int nt[maxm*40][2];
int cnt[maxm*40];
int a[maxm];
int n,m;
void add(int x,int &k,int last){
k=++tot;
int node=k;
for(int i=30;i>=0;i--){
nt[node][0]=nt[last][0];
nt[node][1]=nt[last][1];
int v=(x>>i&1);
nt[node][v]=++tot;
node=nt[node][v];
last=nt[last][v];
cnt[node]=cnt[last]+1;
}
}
int ask(int x,int p,int q){
int ans=0;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
int t=cnt[nt[p][v^1]]-cnt[nt[q][v^1]];
if(t){
p=nt[p][v^1];
q=nt[q][v^1];
ans+=(1<<i);
}else{
p=nt[p][v];
q=nt[q][v];
}
}
return ans;
}
int solve(int x,int l,int r){
return ask(x,rt[r],rt[l-1]);
}
signed main(){
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
add(a[i],rt[i],rt[i-1]);
}
cin>>m;
for(int i=1;i<=m;i++){
int x,l,r;cin>>x>>l>>r;
int ans=solve(x,l,r);
cout<<ans<<endl;
}
return 0;
}