文章目录

  • title
  • solution
  • code

title

魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题。
S 是一个可重集合,S={a1,a2,…,an}。
等概率随机取 S 的一个子集 A={ai1,…,aim}。
计算出 A 中所有元素异或和,记为 x, 求 x^k 的期望。

Input
第一行两个正整数 n, k。
以下 n 行每行一个整数,表示 ai。

Output
如果结果是整数,直接输出。如果结果是小数(显然这个小数是有限的),输出精确值(末尾不加多余的 0)。

Sample Input
4 2 0 1 2 3
Sample Output
3.5

Hint
限制与约定
1≤n≤100000,1≤k≤5,ai≥0。最终答案小于 2^63 。k=1,2,3,4,5 各自占用 20% 的数据

solution

期望=概率*答案值(我一直是这么计算期望这一类题目的)

直接走正解,废话不多说,因为我也不会引入
考虑k=1k=1k=1的情况
我们把答案值ansansans分解成二进制
如果第iii位上为111,那么这个iii就会对答案造成1<<i1<<i1<<i,即2i2^i2i的贡献

那么我们怎么如何确定第iii位是不是111呢?
很简单,看aaa数组里面有多少个数二进制第iii位为111
假设有xxx个,可以知道在这xxx个里面选择的个数的奇偶性会影响最后iii位是否为111
选择了奇数个,异或后就是111,否则就是000
而剩下的n−xn-xn−x个数不管选不选,都不会对iii这一位造成影响,因为这一位上面它们都是000

那么在xxx里面选择个数的奇偶性的概率又分别是多少呢?这里给出一个结论

奇偶性的概率一样,都是12\frac{1}{2}21​


我尽力感性证明一下
举个栗子2,6,102,6,102,6,10,二进制分别为0010,0110,10100010,0110,10100010,0110,1010
就只看从右往左数的第二位(i=1,2ii=1,2^ii=1,2i),都是111对吧。【注意从左往右第一位开始分别是20,21...2^0,2^1...20,21...】
接着分类讨论
如果只选000个,有111种情况
如果只选111个,有333种情况
如果只选222个,有333种情况
如果只选333个,有111种情况

选偶数个的情况总数=>=>=>选000个+++选222个:1+3=41+3=41+3=4
选奇数个的情况总数=>=>=>选111个+++选333个:1+3=41+3=41+3=4
惊奇的一样!!

别急,再煮个栗子12,20,22,1312,20,22,1312,20,22,13,二进制分别是01100,10100,10110,0110101100,10100,10110,0110101100,10100,10110,01101,这一次就只看从左往右数的第三位(i=2,2ii=2,2^ii=2,2i)
如果只选000个,有111种情况
如果只选111个,有444种情况
如果只选222个,有666种情况
如果只选333个,有444种情况
如果只选444个,有111种情况
选偶数个的情况总数=>=>=>选000个+++选222个+++选444个:1+6+1=81+6+1=81+6+1=8
选奇数个的情况总数=>=>=>选111个+++选333个:4+4=84+4=84+4=8
惊奇的又一样!!

而且仔细看这堆数字可以自然地联想到杨辉三角!!(其实是因为上面的情况可以看成组合数)

如果还是觉得很巧,不太有说服性,或者没想通的,我们再另辟蹊径
把这种奇偶选择操作看成按灯泡开关,上图!
已经尽力了总结一下,只要有数能负责iii位,就会有一半的概率产生1<<i1<<i1<<i的贡献


k=2k=2k=2的情况,最高位肯定小于333333,i<33i<33i<33
设f[s][i]f[s][i]f[s][i]表示当选取情况为sss的时候,iii这一位是1/01/01/0,贡献就是f[s][i]2=∑if[s][i]∗∑jf[s][j]=∑i∑jf[s][i]∗f[s][j]f[s][i]^2=\sum_if[s][i]*\sum_jf[s][j]=\sum_i\sum_jf[s][i]*f[s][j]f[s][i]2=i∑​f[s][i]∗j∑​f[s][j]=i∑​j∑​f[s][i]∗f[s][j]
只有i=1,j=1i=1,j=1i=1,j=1才会产生上面的贡献,即为1<<(i+j)=2i+j1<<(i+j)=2^{i+j}1<<(i+j)=2i+j
接着我们来分类讨论,注意i,j表示二进制下的第i位,第j位为1/0
①:i=0∣∣j=0i=0||j=0i=0∣∣j=0
意思就是i,ji,ji,j至少有一个是没有任何数可以负责的,就是没有任何一个数的二进制在那一位上面为111
贡献自然是000
②:i=1&&j=1i=1\&\&j=1i=1&&j=1
结合k=1k=1k=1的情况下,我们知道选完数后要保证iii这一位上的值为111才能对答案产生影响嘛
这个概率是12\frac{1}{2}21​,jjj同理,那么要让i,ji,ji,j同时为111,概率就是12∗12=14\frac{1}{2}*\frac{1}{2}=\frac{1}{4}21​∗21​=41​

但,BUT,However,unfortunately,unluckily

情况不止步于此,我们忽略掉了可能存在一些数二进制i,ji,ji,j位都为111
这样的话如果选择它,就会同步影响i,ji,ji,j,所以我们要重新再分类讨论

结合k=1k=1k=1按灯泡开关的思想,直接上图


其实k>=3k>=3k>=3的情况是最简单的,氧化钙!!
因为答案保证<263<2^{63}<263,考虑第iii位会产生贡献,那么它对答案的影响就是(2i)k(2^i)^k(2i)k,除掉kkk
可以得到i<22i<22i<22,比iii位更大的位置上一定都是000
很容易想嘛,假设i=22i=22i=22这位有111就会产生(1<<22)k(1<<22)^k(1<<22)k,最小的k=3k=3k=3也会炸掉2632^{63}263答案范围
所以我们就直接暴力枚举每一个数选与不选,生成子集AAA,然后去算期望
注意只考虑线性基里面的每一个数,因为线性基可以异或出原数组的每一个数,自然也可以异或出原数组的异或和
记线性基的个数为mmm
一共有2m2^m2m种情况,每一种情况都是12m\frac{1}{2^m}2m1​
用mod=1<<mmod=1<<mmod=1<<m将期望拆开算,不然会炸unsignedlonglongunsigned\ long\ longunsigned long long

code

#include <cstdio>
#define int unsigned long long
#define MAXN 100005
int n, k, ans, cnt, r;
int a[MAXN], f[65], s[65];
bool vis[65];int read() {int x = 0; char s = getchar();while( s < '0' || s > '9' ) s = getchar();while( '0' <= s && s <= '9' )x = ( x << 1 ) + ( x << 3 ) + ( s - '0' ), s = getchar();return x;
}void solve1() { for( int i = 1;i <= n;i ++ ) ans |= a[i];if( ans & 1 ) printf( "%llu.5", ans >> 1 );else printf( "%llu", ans >> 1 );
}bool check( int i, int j ) {if( ! vis[i] || ! vis[j] ) return 0;for( int t = 1;t <= n;t ++ ) {if( ( a[t] & ( 1ll << i ) ) && ! ( a[t] & ( 1ll << j ) ) )return 0;if( ( a[t] & ( 1ll << j ) ) && ! ( a[t] & ( 1ll << i ) ) )return 0;}return 1;
}void solve2() {for( int i = 0;i < 33;i ++ )for( int j = 1;j <= n;j ++ )if( a[j] & ( 1ll << i ) ) { vis[i] = 1; break; }for( int i = 0;i < 33;i ++ )for(int j = i;j < 33;j ++ )if( vis[i] && vis[j] ) ans += ( 1ll << ( i + j ) );for( int i = 0;i < 33;i ++ )for( int j = i + 1;j < 33;j ++ )if( check( i, j ) ) ans += ( 1ll << ( i + j ) );if( ans & 1 ) printf( "%llu.5", ans >> 1 );else printf( "%llu", ans >> 1 );
}void calc( int val ) {int mod = 1ll << cnt;int D = 0, R = 1;for( int i = 1;i <= k;i ++ )D = D * val, R = R * val, D += R / mod, R %= mod;ans += D, r += R, ans += r / mod, r %= mod;
}void dfs( int x, int val ) {if( x > cnt ) { calc( val ); return; }dfs( x + 1, val ); dfs( x + 1, val ^ s[x] );
}void solve3() {for( int i = 1;i <= n;i ++ ) {int val = a[i];for( int j = 21;~ j;j -- )if( ( 1ll << j ) & val )if( f[j] ) val ^= f[j];else { f[j] = val; break; }}for( int i = 0;i <= 21;i ++ )if( f[i] ) s[++ cnt] = f[i];dfs( 1, 0 );if( r ) printf( "%llu.5", ans );else printf( "%llu", ans );
}signed main() {n = read(); k = read();for( int i = 1;i <= n;i ++ )a[i] = read();if( k == 1 ) solve1();else if( k == 2 ) solve2();else solve3();return 0;
}

[BZOJ 3811]玛里苟斯(线性基)尽量理解的题解相关推荐

  1. bzoj 3811 玛里苟斯 - 线性基

    题目传送门 传送门I 传送门II 题目大意 给定集合$S$,问集合$S$的任意选一个子集的异或和的$k$次幂期望. 保证答案在$2^{63}$内. 注意到答案在$2^{63}$内,所以,当$k \ge ...

  2. [清华集训D1T1][Bzoj 3811][思维+线性基]玛里苟斯

    想像一下,我们将异或值x拆成若干个2的次方加在一起,那么k次方的意义便是: 从这些2次方中挑出k个(有序)2次方,将它们乘起来的和. 具体一点,bi是x的二进制表达从右往左的第i+1位,于是x可以拆成 ...

  3. bzoj 3811: 玛里苟斯(期望+线性基)

    3811: 玛里苟斯 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 223  Solved: 98 [Submit][Status][Discuss ...

  4. bzoj 3811: 玛里苟斯【线性基+期望dp】

    这个输出可是有点恶心啊--WA*inf,最后抄了别人的输出方法orz 还有注意会爆long long,要开unsigned long long 对于k==1,单独考虑每一位i,如果这一位为1则有0.5 ...

  5. bzoj 3811: 玛里苟斯

    3811: 玛里苟斯 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 190  Solved: 95 [Submit][Status][Discuss ...

  6. 2460: [BeiJing2011]元素 有关线性基的理解

    题意比较简单吧,就是要你求一对魔法石的集合,并且这些东西都是线性无关的,要是集合的魔力值总和最大 总的来说就是一个线性基模板题.. 我们先将他排序,接着贪心地插入就好了,正确性可以类比于最小生成树,匈 ...

  7. [清华集训2015 Day1]玛里苟斯-[线性基]

    Description Solution 考虑k=1的情况.假设所有数中,第i位为1的数的个数为x,则最后所有的子集异或结果中,第i位为1的个数为$(C_{k}^{1}+C_{k}^{3}+...)$ ...

  8. [清华集训2014]玛里苟斯(线性基+概率期望)

    首先有一些前置引理: 1. 由期望的线性性,平方的期望不等于期望的平方,所以求k次方的期望时,需要记录1~k-1的期望,然后计算增量(OSU!),这个这题没用上. 2. 线性基是可以变成每位只在一个元 ...

  9. BZOJ 4184 shallot 线性基+分治

    Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且让小葱从 ...

最新文章

  1. 【UVA/Codeforces】1584 Circular Sequence / 792B Counting-out Rhyme(就是一个圈儿...)
  2. The next Industry Standard in IT Monitoring, a python implementation Nagios like tool --- Shinken
  3. 优秀案例:12个精美的设计工作室 设计公司网站
  4. junit测试@注解
  5. wxWidgets:wxInitDialogEvent类用法
  6. 北航成教计算机课程,成教生:从问题学生到北航计算机本科生
  7. android 框架_AOP编程_Android优雅权限框架(2)Demo完全解析
  8. 【Vue】路由Router嵌套的实现及经典案例
  9. 苹果收购倒闭智能家居安防初创公司 Lighthouse AI 专利...
  10. 【JS】js打开新窗口与页面跳转
  11. 计算信源熵和香农编码C语言,信息论与编码课程设计报告统计信源熵与香农编码...
  12. 规则引擎groovy
  13. 计算机平板传输软件,如何在iPad和电脑之间无线传输文件
  14. 【MindSpore易点通机器人-01】你也许见过很多知识问答机器人,但这个有点不一样
  15. js table 生成序号_JS自动为表格增加序号
  16. Java微服务实战项目推荐
  17. 影响未来的十大网络技术
  18. ubuntu中安装比较工具meld及其使用
  19. telnet无法打开到主机的连接。 在端口 23: 连接失败
  20. 基于强化学习SAC_LSTM算法的机器人导航

热门文章

  1. pythonocc常见问题集锦
  2. 2018年陕西文科生可以报计算机专业am,2018年高考志愿:文科生,可以报考哪些专业!...
  3. php date函数 在哪里,PHP date函数
  4. ajax+json自动提示Demo
  5. 认识1M带宽、1Mbps、1Mb/s 区分
  6. multisim怎么设置晶体管rbe_multisim中三极管参数
  7. [刷机教程] [Root] S-OFF的同学来Root你的HTC Desire S
  8. 《千与千寻》再上映:18年后才发现,这是一部成年人的电影
  9. Always Day1 学会爱自己才能好好爱别人
  10. 高云FPGA系列教程(基于GW1NSR-4C TangNano 4K开发板)