【题目描述】
UVALive - 8512XOR
【题目分析】
这种区间+线性基的问题我们可以考虑用线段树维护,线性基的合并的话就直接暴力合并
找到所在区间的线性基后再查找最大的数,我看网上的博客要说消除k的影响什么的,我觉得没有什么必要,直接将初值设置为k,然后从高位向低位找,如果异或了后值会变大就异或,觉得没有什么大问题。还有就是线段树维护的时候函数的返回值最好不要设置成线性基,会RE,具体的为什么我也不清楚。这道题的RE很玄学,我把读入数据改成longlong就会RE,T和u,v里面都一个不是longlong就不会RE,我提交了20多次才敢确定的确是因为这个原因导致RE,emmm,比较玄学
【AC代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<climits>
#include<cstdlib>
#include<cmath>using namespace std;typedef long long ll;const int MAXN=10005;
int n,m,kk;
int a[MAXN];
struct L_B
{ll b[65],p[65];int cnt,flag;L_B(){memset(p,0,sizeof(p));memset(b,0,sizeof(b));cnt=flag=0;}void clear(){memset(p,0,sizeof(p));memset(b,0,sizeof(b));cnt=flag=0;}inline bool insert(ll x){for(int i=62;i>=0;--i)if(x&(1ll<<i)){if(b[i])x^=b[i];else{b[i]=x;return true;}}flag=1;return false;}ll get_max(){ll ret = 0;for(int i=62;i>=0;--i)if((ret^b[i])>ret)ret^=b[i];return ret;}ll get_max(ll initval){ll ret = initval;for(int i=62;i>=0;--i)if((ret^b[i])>ret)ret^=b[i];return ret;}ll get_min(){if(flag)return 0;for(int i=0;i<=62;++i)if(b[i])return b[i];return 0;}inline void rebuild(){for(int i=1;i<=62;++i)if(b[i])for(int j=0;j<i;++j)if(b[i]&(1ll<<j))b[i]^=b[j];for(int i=0;i<=62;++i)if(b[i])p[cnt++]=b[i];}ll kth(ll k){if(flag)--k;if(k==0)return 0;ll ret = 0;if(k>=(1ll<<cnt))return -1;for(int i=0;i<=cnt-1;++i)if(k&(1ll<<i))ret^=p[i];return ret;}
};
L_B A;
struct node
{L_B lis;
}tree[MAXN<<2];L_B merge(const L_B &n1,const L_B &n2)
{L_B ret = n1;for(int i = 0;i <= 62;++i)if(n2.b[i])ret.insert(n2.b[i]);ret.flag = n1.flag | n1.flag;return ret;
}void build(int k,int l,int r)
{if(l==r){tree[k].lis.insert(a[l]);return;}int mid=(l+r)>>1;build(k<<1,l,mid); build(k<<1|1,mid+1,r);tree[k].lis=merge(tree[k<<1].lis,tree[k<<1|1].lis);
}void query(ll k,ll l,ll r,ll L,ll R)
{if(l>=L && r<=R){A=merge(A,tree[k].lis);return;}int mid=(l+r)>>1;if(L<=mid) query(k<<1,l,mid,L,R);if(R>mid) query(k<<1|1,mid+1,r,L,R);return ;
}int main()
{ll T,u,v;scanf("%lld",&T);while(T--){scanf("%d%d%d",&n,&m,&kk);for(int i=1;i<=n;i++) scanf("%d",&a[i]);build(1,1,n);for(int i=0;i<m;i++){A.clear();scanf("%lld%lld",&u,&v);query(1,1,n,u,v);printf("%lld\n",A.get_max(kk));}}return 0;
}