码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-10-05 16:09:51      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:ret   html   logs   closed   scan   play   ++   hid   main   

已知一个长度为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就是要第一个出场:线性基

标签:ret   html   logs   closed   scan   play   ++   hid   main   

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11624654.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!