线段树维护线性基并——17西安icpc a

#include
using namespace std;
#define N 10005

int a[N],n,k,q;

struct LB{
    int b[35];
    LB(){memset(b,0,sizeof b);}
    int check(int x){
        for(int i=29;i>=0;i--)if(x>>i & 1){
            if(!b[i])return 0;
            x^=b[i];
        }
        return 1;
    }
    void insert(int x){
        for(int i=29;i>=0;i--)if(x>>i & 1){
            if(!b[i]){b[i]=x;return;}
            x^=b[i];
        }
    }
    int query_max(){
        int res=0;
        for(int i=29;i>=0;i--)
            res=max(res,res^b[i]);
        return res;
    }
};

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
LB seg[N<<2];
LB merge(LB A,LB B){
    LB res;
    for(int i=29;i>=0;i--)
        res.b[i]=A.b[i];
    for(int i=29;i>=0;i--)
        if(B.b[i])
            res.insert(B.b[i]);
    return res;
}
void build(int l,int r,int rt){
    if(l==r){
        seg[rt].insert(a[l]);
        return;
    }
    int m=l+r>>1;
    build(lson);build(rson);
    seg[rt]=merge(seg[rt<<1],seg[rt<<1|1]); 
}
LB query(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r)return seg[rt];
    int m=l+r>>1;
    LB res;
    if(L<=m)res=merge(res,query(L,R,lson));
    if(R>m)res=merge(res,query(L,R,rson));
    return res;
}

void init(){
}

int main(){
    int t;cin>>t;while(t--){
        cin>>n>>q>>k;
        for(int i=1;i<=n;i++){
            /*k的存在会对求线性基最大值时的主元产生影响,所以预处理,a[i]只保留k没有的位*/ 
            scanf("%d",&a[i]);
            for(int j=0;j<30;j++)
                if((k>>j & 1) && (a[i]>>j & 1))
                    a[i]^=(1<<j);
        }
        
        build(1,n,1); 
        while(q--){
            int L,R;scanf("%d%d",&L,&R);
            LB res=query(L,R,1,n,1);
            cout<<(res.query_max()|k)<<'\n';
        }
    }
} 

 

你可能感兴趣的:(线段树维护线性基并——17西安icpc a)