albus就是要第一个出场:线性基

Posted $DeepinC$

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了albus就是要第一个出场:线性基相关的知识,希望对你有一定的参考价值。

已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n },

S 的幂集2^S定义为S 所有子集构成的集合。

定义映射 f : 2^S -> Z

f(空集) = 0

f(T) = XOR A[t](异或和)

 对于一切t属于T现在albus把2^S中每个集合的f值计算出来, 从小到大排成一行, 记为序列B(下标从1开始)。

给定一个数, 那么这个数在序列B中第1次出现时的下标是多少呢?

 

呃啊啊还我们一个可视的题面。

 

这是个结论题。。。

结论:

n个数构成的线性基有k个时,那么这n个数的全部子集的异或和刚好就是线性基k个数能拼成的2k个数,每个数有2n-k个。

证明也许比较显然?

然后这题就可做了。

好无聊。。。结论题什么的。。。

但是有什么办法呢?只能记住吧。

写这篇博客的目的就是为了存一下结论。

以及推荐blog:rvalue

里面有结论的感性证明。

 

有了结论,代码倒挺好写的。

 1 #include<cstdio>
 2 #define mod 10086
 3 int pw(int b,int t,int a=1){for(;t;t>>=1,b=b*b%mod)if(t&1)a=a*b%mod;return a;}
 4 int base[33];
 5 int main(){
 6     int n,N,x,cnt=0,ans=0;scanf("%d",&n);N=n;
 7     while(n--){
 8         scanf("%d",&x);
 9         for(int i=30;~i;--i)if(!base[i]&&x&1<<i){base[i]=x;break;}
10             else if(x&1<<i)x^=base[i];
11     }
12     scanf("%d",&x);
13     for(int i=30;~i;--i)if(base[i]&&x&1<<i)cnt++,ans=(ans+pw(2,N-cnt))%mod;
14         else if(base[i])cnt++;
15     printf("%d\\n",ans+1);
16     
17 }
View Code

 

以上是关于albus就是要第一个出场:线性基的主要内容,如果未能解决你的问题,请参考以下文章

线性基bzoj2844: albus就是要第一个出场

albus就是要第一个出场:线性基

BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基

BZOJ2844albus就是要第一个出场 高斯消元求线性基

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

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