2017 ICPC西安区域赛 A - XOR ,线段树合并线性基

题目链接:A - XOR

题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值

题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后在求一下。每个数先与~k与一下对于k为1的位答案时这位肯定为1,就去掉影响,然后其他位的最大异或和在于k或一下就可以啦

#include<bits/stdc++.h>
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e4+5;
int n,q,a[N];
unsigned int k;
struct L_B
{
    ll a[65];
    void init()
    {
        memset(a,0,sizeof(a));
    }
    bool insert(ll val)
    {
        for(int i=63;i>=0;i--)
        {
            if(val&(1ll<<i))
            {
                if(!a[i])
                {
                    a[i]=val;
                    break;
                }
                else val^=a[i];
            }
        }
        return val>0;
    }
    ll query_max()
    {
        ll ret=0;
        for(int i=63;i>=0;i--)
        {
            if((ret^a[i])>ret)
            {
                ret^=a[i];
            }
        }
        return ret;
    }
    L_B merge(L_B m)
    {
        L_B ret;
        for(int i=0;i<64;i++)
        {
            ret.a[i]=a[i];
        }
        for(int i=0;i<64;i++)
        {
            ret.insert(m.a[i]);
        }
        return ret;
    }
}tr[N];
void build(int l,int r,int rt)
{
    tr[rt].init();
    if(l==r)
    {
        tr[rt].insert(a[l]);
        return ;
    }
    int m=l+r>>1;
    build(ls);
    build(rs);
    tr[rt]=tr[rt<<1].merge(tr[rt<<1|1]);
}
L_B query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return tr[rt];
    }
    int m=l+r>>1;
    L_B ret;ret.init();
    if(L<=m)ret=ret.merge(query(L,R,ls));
    if(R>m)ret=ret.merge(query(L,R,rs));
    return ret;
}
int main() {
   int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d %u",&n,&q,&k);
        k=~k;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            a[i]&=k;
        }
        k=~k;
        build(1,n,1);
        while(q--)
        {
            int l,r;
            scanf("%d %d",&l,&r);
            L_B ans=query(l,r,1,n,1);
            ll an=ans.query_max();
            an|=k;
            printf("%lld\n",an);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/lhclqslove/p/9754858.html