题目链接:http://codeforces.com/contest/1100/problem/F
构造线性基的同时,维护每一个基向量出现的最靠右的位置即可,然后离线所有的查询即可,第一次见这种套路
代码:
#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN=5e5+5;
const int MAXL=20;//位数
typedef long long ll;
template<typename Tp>
struct LinearBasis
{
Tp v[MAXL+1];
int pos[MAXL+1];
int sz,n;
LinearBasis()
{
memset(v,0,sizeof(v));
}
//上三角矩阵
void add(Tp x,int p)
{
for(int i=MAXL;i>=0;i--)
{
if(x&(1LL<<i))
{
if(!v[i])
{
v[i]=x;
pos[i]=p;
break;
}
if(pos[i]<p)
{
swap(p,pos[i]);
swap(x,v[i]);
}
x^=v[i];
}
}
}
Tp queryMax(int l)
{
Tp x=0;
for(int i=MAXL;i>=0;i--)
{
if(pos[i]<l) continue;
x=max(x,x^v[i]);
}
return x;
}
};
LinearBasis<int> lb;
vector<pii> evt[MAXN];
int c[MAXN],ans[MAXN];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,q;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int l,r;
scanf("%d%d",&l,&r);
evt[r].pb(mp(l,i));
}
for(int i=1;i<=n;i++)
{
lb.add(c[i],i);
for(auto it:evt[i])
{
int l=it.xx;
int id=it.yy;
ans[id]=lb.queryMax(l);
}
}
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
return 0;
}