这题做法很早就想到了,就是先对ai^=(~k),消去k的位对查询区间异或和最大值的影响,然后查询区间[l,r]区间异或和最大值ans,答案就是k|ans,但是卡在了区间异或最大值这里,我当时只会线性基on插区间最大值,帅帅在用线段树做,但是re了,
(多说一句,uva真的坑,只要不ce和re全判ac,什么垃圾oj。。)后来我们发现判题全ac就没继续打了
思路:思路就是上面说的,唯一的难点就是区间异或最大值了,详见代码
Consider an array AAA with n elements . Each of its element is A[i]A[i]A[i] (1≤i≤n)(1 \le i \le n)(1≤i≤n) . Then gives two integers QQQ, KKK, and QQQ queries follow . Each query , give you LLL, RRR, you can get ZZZ by the following rules.
To get ZZZ , at first you need to choose some elements from A[L]A[L]A[L] to A[R]A[R]A[R] ,we call them A[i1],A[i2]…A[it]A[i_1],A[i_2]…A[i_t]A[i1],A[i2]…A[it] , Then you can get number Z=KZ = KZ=K or (A[i1]A[i_1]A[i1] xor A[i2]A[i_2]A[i2] … xor A[it]A[i_t]A[it]) .
Please calculate the maximum ZZZ for each query .
Input
Several test cases .
First line an integer TTT (1≤T≤10)(1 \le T \le 10)(1≤T≤10) . Indicates the number of test cases.Then TTT test cases follows . Each test case begins with three integer NNN, QQQ, KKK (1≤N≤10000, 1≤Q≤100000, 0≤K≤100000)(1 \le N \le 10000,\ 1 \le Q \le 100000 , \ 0 \le K \le 100000)(1≤N≤10000, 1≤Q≤100000, 0≤K≤100000) . The next line has NNN integers indicate A[1]A[1]A[1] to A[N]A[N]A[N] (0≤A[i]≤108)(0 \le A[i] \le 10^8)(0≤A[i]≤108). Then QQQ lines , each line two integer LLL, RRR (1≤L≤R≤N)(1 \le L \le R \le N)(1≤L≤R≤N) .
Output
For each query , print the answer in a single line.
样例输入
1 5 3 0 1 2 3 4 5 1 3 2 4 3 5
样例输出
3 7 7
题目来源
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<map>
//#define ll long long
#define ll int
#include <iostream>
#include <math.h>
using namespace std;
#define maxn 10000+5
ll d[maxn][35],a[maxn],pos[maxn][35];//线性基数组
void add(int now,ll x)//添加x
{
for(int i=30;i>=0;i--) d[now][i]=d[now-1][i],pos[now][i]=pos[now-1][i];
int h=now;
for(int i=30;i>=0;i--)
{
if(x&(1ll<<i))
{
if(d[now][i])
{
if(pos[now][i]<h)
{
swap(pos[now][i],h);
swap(d[now][i],x);
}
x^=d[now][i];
}
else
{
d[now][i]=x;
pos[now][i]=h;
break;
}
}
}
}
ll Max(int l,int r)//从数组中去任意个使异或和最大
{
ll ans=0;
for(int i=30;i>=0;i--)
{
if((pos[r][i]>=l)&&((ans^d[r][i])>ans)) ans^=d[r][i];
}
return ans;
}
int main()
{
/*int n;
while(scanf("%d",&n)!=EOF)
{
memset(d,0,sizeof(d));
for(int i=1;i<=n;i++)
{
ll x;
cin>>x;
add(x);
}
ll ans=Min();
cout<<ans<<'\n';
}*/
int t;
scanf("%d",&t);
while(t--)
{
memset(pos,0,sizeof(pos));
memset(d,0,sizeof(d));
int n,q,k;
scanf("%d %d %d",&n,&q,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]&=(~k);
}
for(int i=1;i<=n;i++)
{
add(i,a[i]);
}
while(q--)
{
int l,r;
scanf("%d %d",&l,&r);
int ans=Max(l,r);
printf("%d\n",k|ans);
}
}
}