题解:P17146 [ICPC 2017 Xi'an R] XOR
shimizu_kiouka · · 题解
P17146 [ICPC 2017 Xi'an R] XOR 题解。
题目大意:给你一个序列,每次询问一个区间,允许从区间里挑选若干个元素,求这些元素的异或值再与
前置内容:线性基,线段树。
我们可以先不考虑
那么怎么处理
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=101010,BASE=60;
ll t;
ll n,q,k;
ll x;
ll l,r;
struct segtr{
ll p[61];
int ps[61];
segtr(){
memset(p,0,sizeof(p));
memset(ps,0,sizeof(ps));
}
}tree[MAXN];
void insert(segtr &u,ll x,int id){
for(int i=BASE;i>=0;i--){
if(!(x>>i&1)) continue;
if(!u.p[i]){
u.p[i]=x;
u.ps[i]=id;
break;
}
if(u.ps[i]<id){
swap(u.p[i],x);
swap(u.ps[i],id);
}
x^=u.p[i];
}
}
ll query(const segtr &u,int l){
ll r=0;
for(int i=BASE;i>=0;--i){
if(u.ps[i]>=l && (r^u.p[i])>r) r^=u.p[i];
}
//线性基求最大
return r;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n>>q>>k;
memset(tree[0].p,0,sizeof(tree[0].p));
memset(tree[0].ps,0,sizeof(tree[0].ps));
for(int i=1;i<=n;i++){
cin>>x;
x&= ~(ll)k;//预处理
tree[i]=tree[i-1];
insert(tree[i],x,i);
}
while(q--){
cin>>l>>r;
cout<<(query(tree[r],l)|k)<<'\n';//查询后按位或k
}
}
}