bzoj千题计划195:bzoj2844: albus就是要第一个出场

http://www.lydsy.com/JudgeOnline/problem.php?id=2844

 

题意:给定 n个数,把它的所有子集(可以为空)的异或值从小到大排序得到序列 B,请问 Q 在 B 中第一次出现的下标是多少?保证 Q 在 B 中出现。

 

如果去除重复数,根据Q的二进制便可以得到答案

现在不去除重复数

结论:每个数都会重复出现2^(n-|β|) 次

证明:摘自https://blog.sengxian.com/algorithms/linear-basis

 

 

#include<cstdio>
#include<iostream>

using namespace std;

#define N 100001

const int mod=10086;

int a[N];
int b[31];

int res[31];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

int pow(int x,int y)
{
    int r=1;
    for(;y;y>>=1,x=x*x%mod)
        if(y&1) r=r*x%mod;
    return r;
}

int main()
{
    int n;
    read(n);
    for(int i=1;i<=n;++i) read(a[i]);
    for(int i=1;i<=n;++i)
        for(int j=30;j>=0;--j)
            if(a[i]>>j&1)
            {
                if(!b[j])
                {
                    b[j]=a[i];
                    break;
                }
                a[i]^=b[j];
            }
    int cnt=0;
    for(int i=0;i<=30;++i)
        if(b[i]) res[cnt++]=i;
    int m;
    read(m);
    int rk=0;
    for(int i=0;i<cnt;++i)
        if(m>>res[i]&1) rk+=1<<i; 
    rk%=mod;
    rk=rk*pow(2,n-cnt)%mod;
    cout<<(rk+1)%mod;
}

 

posted @ 2018-01-05 18:02  TRTTG  阅读(189)  评论(0编辑  收藏  举报