bzoj 2844: albus就是要第一个出场

(一眼看上去线性基的大水题啊,写完线性基,然后处理了一下,尽量是的每个线性基的最高位且只有最高位是1,然后我就开心的开始算m是第几了,,,呵呵呵)

本题的正确姿势,,,在我开心之后,再乘以一个2^(n-tot),(tot是不为0线性基个数),,,

线性基只能构造出2^tot,然而集合子集有2^n个,,(所以就乘个2^(n-tot),,,,(大雾)),为什么相等也不知道,可能神犇都能yy出吧,反正本蒟蒻yy一下感觉没道理。

(数学这么优美的东西,肯定要一样多的,(大雾))

(哦,对了,这里的线性基可以高斯消元求,也可以直接那么抑或构造,然后在用线性基互相抑或一下只留最高位1)

  1 /*#include<bits/stdc++.h>
  2 #define N 100005
  3 #define LL long long
  4 #define inf 0x3f3f3f3f
  5 using namespace std;
  6 inline int ra()
  7 {
  8     int x=0,f=1; char ch=getchar();
  9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 11     return x*f;
 12 }
 13 int ksm(int a, int b)
 14 {
 15     int sum=1;
 16     for(;b;b>>=1,a=a*a%10086)
 17         if (b&1) sum=sum*a%10086;
 18     return sum%10086; 
 19 }
 20 int k,cnt,m,a[N],p[105];
 21 int b[N];
 22 void guass()
 23 {
 24     k=cnt;
 25     for (int i=1; i<=cnt; i++){
 26         for (int j=i+1; j<=cnt; j++)
 27             if (a[j]>a[i])
 28                 swap(a[i],a[j]);
 29         if (!a[i]) {
 30             k=i-1;
 31             break;
 32         }
 33         for (int j=31; ~j; j--)
 34             if ((a[i]>>j)&1){
 35                 b[i]=j;
 36                 for (int k=1; k<=cnt; k++)
 37                     if (k!=i && (a[k]>>j)&1)
 38                         a[k]^=a[i];
 39                 break;
 40             }
 41     }
 42 }
 43 int main()
 44 {
 45     cnt=ra(); 
 46     for (int i=1; i<=cnt; i++) a[i]=ra();
 47     m=ra();
 48     if (m==0){cout<<"1";return 0;}
 49     guass();
 50     int ans=1;
 51     for (int i=1; i<=k; i++)
 52         if ((m>>b[i])&1)
 53         {
 54             m^=a[i];
 55             ans=(ans+ksm(2,cnt-i))%10086;
 56         }
 57     cout<<ans;
 58     return 0;
 59 } */
 60 #include<bits/stdc++.h>
 61 #define N 100005
 62 #define LL long long
 63 #define inf 0x3f3f3f3f
 64 using namespace std;
 65 inline LL ra()
 66 {
 67     LL x=0,f=1; char ch=getchar();
 68     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 69     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 70     return x*f;
 71 }
 72 int ksm(int a, int b)
 73 {
 74     int sum=1;
 75     for(;b;b>>=1,a=a*a%10086)
 76         if (b&1) sum=sum*a%10086;
 77     return sum%10086; 
 78 }
 79 int n,m,a[N],p[105],b[105],tot;
 80 bool flag;
 81 int main()
 82 {
 83     n=ra(); 
 84     for (int i=1; i<=n; i++) a[i]=ra();
 85     m=ra();
 86     if (m==0){cout<<"1";return 0;}
 87     for (int i=1; i<=n; i++)
 88         for (int j=30; ~j; j--)
 89             if ((1<<j)&a[i])
 90             {
 91                 if (!p[j]) 
 92                 {
 93                     p[j]=a[i];
 94                     break;
 95                 }
 96                 a[i]^=p[j];
 97                 if (!a[i]) flag=1;
 98             }
 99     int cnt=0;
100     for (int i=30; ~i; i--)
101     {
102         if (!p[i]) {continue;} 
103         for (int j=i-1; ~j; j--)
104             if (p[i]&(1<<j))
105                 p[i]^=p[j];
106     }
107     for (int i=0; i<=30; i++)
108         if (p[i]) b[++tot]=i;
109     int ans=0;
110     for (int i=1; i<=tot; i++)
111         if ((m>>b[i])&1)
112         {
113             m^=p[i-1];
114             ans+=(1<<(i-1))%10086;
115             ans%=10086;
116         }
117     cout<<1+(ans*ksm(2,n-tot))%10086;
118     return 0;
119 } 

 

posted @ 2017-02-23 20:48  ws_ccd  阅读(196)  评论(0编辑  收藏  举报