[bzoj2844]albus就是要第一个出场

线性基中的所有数一定能够造出所有异或的结果,同时一定只有一种方式(否则这两种方式异或起来为0),那么只需要考虑为了异或出X,每一位的线性基要不要选,若X的这一位是1,那么别的方案一定可以使得这一位是0,因此会增加$2^{剩下的线性基个数}$个比X小的数,否则不会增加
还有重复数字,可以发现除了线性基外的数字任意一种选法都可以与线性基中的数字异或得到某个数字,所以每一个数字重复次数都是$2^{线性基外的数字个数}$,计算一下即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 10086
 4 int n,k,ans,a[101],sum[101];
 5 void add(int k){
 6     for(int i=31;i>=0;i--)
 7         if (k&(1<<i)){
 8             if (!a[i]){
 9                 a[i]=k;
10                 return;
11             }
12             k^=a[i];
13         }
14 }
15 int main(){
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++){
18         scanf("%d",&k);
19         add(k);
20     }
21     scanf("%d",&k);
22     sum[0]=a[0];
23     for(int i=1;i<32;i++)sum[i]=sum[i-1]+(a[i]>0);
24     for(int i=0;i<32;i++)
25         if ((a[i])&&(k&(1<<i)))ans=(ans+(1<<sum[i]-1))%mod;
26     for(int i=1;i<=n-sum[31];i++)ans=ans*2%mod;
27     printf("%d",ans+1);
28 }
View Code

 

posted @ 2019-08-07 19:54  PYWBKTDA  阅读(112)  评论(0编辑  收藏  举报