XOR1

传送门:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
#define re register
#define ll long long
const int N=1e6+10;
const int mod=1e9+7;
inline void read(ll &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
inline void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
ll q[N],a[65],b[65],c[65],s[65],t[65],cnt,tot,n;
bool f[N];
inline bool ins(ll x,ll t[])
{
    for(re int i=63;i>=0;i--)
        if((1ll<<i)&x)
        {
            if(!t[i])
            {
                t[i]=x;
                t[64]++;
                return 1;
            }
            x^=t[i];
        }
    return 0;
}
inline ll quickmod(ll k)
{
    ll res=1;
    ll base=2;
    while(k)
    {
        if(k&1)
            res=res*base%mod;
        base=base*base%mod;
        k>>=1;
    }
    return res;
}
inline bool solve(ll x)
{
    for(re int i=63;i>=0;i--)
        if((1ll<<i)&x)
            x^=c[i];
    return !x;
}
int main()
{
    while(~scanf("%d",&n))
    {
        cnt=tot=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(re int i=0;i<n;i++)
            read(q[i]),f[i]=0;
        for(re int i=0;i<n;i++)
            if(ins(q[i],a))
                f[i]=1,s[cnt++]=q[i];
        ll ans=0;
        //for(re int i=0;i<cnt;i++)
            //cout<<s[i]<<" ";
        //cout<<endl;
        ans+=1ll*(n-a[64])*quickmod(n-a[64]-1)%mod;///筛出一个线性基后随便找一些不是线性基里面的数都能组合成异或和为0的基,为了保证取一个所以是(n-a[64]-1)
        //cout<<ans<<endl;
        for(re int i=0;i<n;i++)
            if(!f[i])
                ins(q[i],b);///筛出另外一个线性基
        for(re int i=0;i<cnt;i++)
        {
            memset(c,0,sizeof(c));
            for(re int j=0;j<cnt;j++)
                if(j!=i)
                    ins(s[j],c);
            for(re int j=63;j>=0;j--)
                if(b[j])
                    ins(b[j],c);
            if(solve(s[i]))
                (ans+=quickmod(n-c[64]-1))%=mod;
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/acm1ruoji/p/11289508.html