(线性基)Operation

http://acm.hdu.edu.cn/showproblem.php?pid=6579

线性基https://blog.csdn.net/a_forever_dream/article/details/83654397

模板https://blog.csdn.net/u013534123/article/details/79875825

我们考虑在每个位置求出首位置到当前位置的线性基。同时我们要使线性基中高位的位置所选的数尽量靠后。这样我们维护线性基的时候在同时维护一个位置信息就好了。

#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<stack>
#include<cmath>
#include<iostream>
#define ll long long
#define lowbit(x) x&(-x)
#define maxn 1050000
#define inf 0x3f3f3f3f
using namespace std;
int a[maxn][35]; //存线性基 
int b[maxn][35]; //存位置 
int k;
void add(int x)
{
    int cur=++k;
    for(int i=31;i>=0;i--)
    {
        a[k][i]=a[k-1][i];
        b[k][i]=b[k-1][i];
    }
    for(int i=31;i>=0;i--)
    {
        if(x>>i)
        {
            if(!a[k][i])
            {
                a[k][i]=x;
                b[k][i]=cur;
                break;
            }
            else
            {
                if(cur>b[k][i])
                {
                    swap(a[k][i],x);
                    swap(b[k][i],cur);
                }
                x^=a[k][i];
            }
        }
    }
}
int query(int l,int r)
{
    l=l%k+1;
    r=r%k+1;
    if(l>r)
    swap(l,r);
    int ret=0;
    for(int i=31;i>=0;i--)
    {
        if(b[r][i]>=l)
        {
            ret=max(ret,a[r][i]^ret);
        }
    }
    return ret;
} 
int main()
{
    int t;
    scanf("%d",&t);
    int n,m;
    while(t--)
    {
        k=0;
        scanf("%d%d",&n,&m);
        int x;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            add(x);
        }
        int op,y,ans=0;
        while(m--)
        {
            scanf("%d %d",&op,&x);
            if(op==0)
            {
                scanf("%d",&y);
                ans=query(x^ans,y^ans);
                printf("%d
",ans);
            }
            else
            {
                add(x^ans);
            }
        }
    }
}
原文地址:https://www.cnblogs.com/2462478392Lee/p/11573629.html