博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj3811】【清华集训2014】玛里苟斯
阅读量:7243 次
发布时间:2019-06-29

本文共 2969 字,大约阅读时间需要 9 分钟。

3811: 玛里苟斯

Time Limit: 10 Sec 
Memory Limit: 256 MB

Submit: 500 
Solved: 196

[ ][ ][ ]

Description

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

 

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% 的数据

 

 

Source

[ ][ ][ ]

 

题解:

        wwwwodddd   ORZ

       求子集异或和k次方的期望;

       首先这和期望的k次方不一样,所以还是老老实实按k分类讨论,按位算贡献吧:

       k=1 , 考虑第i位是否有1,有会贡献的$2^{i-1} $, 全部或起来除二;

       k=2,如果某个异或和的第i位和第j为都有值,会贡献$2^{i+j}$的答案 , 首先这两位都必须要有至少一个1;

               紧接着如果对于每一个数来说,这两位的值都相同 ,说明两位不相互独立,所以概率是1/2,期望是$2^{i+j-1}$;

               否则说明两位独立,在异或运算下(0,0)(0,1)(1,0)(1,1)的概率相同为1/4,期望是$2^{i+j-2}$;

       k>=3 , 由于答案在2^63次方以内,所以线性基的大小不会超过22,直接暴力枚举计算期望;

       这题有一个结论是答案*2一定是整数;

      也就是答案的小数最多有一位;

      

这里有个评论证明了,但是我没太看懂:https://blog.sengxian.com/solutions/bzoj-3811自己给出一个可能不太严谨的证明吧(没学过数学。。。):可以仔细分析一下k==2时的算法;再扩展到k次方,发现在异或运算下:二进制位之间贡献不相互独立是具有传递性的;假设一次计算答案时选定的k个二进制位(可能相同分)集合为:B  = {b1,b2,...bk}我们可以把他们进一步分成m个集合:S1...Sm相同集合元素贡献不互相独立,不同集合贡献互相独立;这时对答案期望的贡献应该是2^{b1+b2+...+bk - m}  ;而k >= m , 且B里面至少有m个不同的二进制位(即bi!=bj这种);所以考虑b1+b2+...+bk - m最小的情况:分析可以发现最小为-1;所以答案小数点后只有一位;。。。。。。
如果你感兴趣的话

 

       这样就可以用一个数存下对2^|B|的除数和余数,分类讨论小数位的情况(建议看下代码);

 

 

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #define Run(i,l,r) for(int i=l;i<=r;i++)12 #define Don(i,l,r) for(int i=l;i>=r;i--)13 #define ll unsigned long long14 #define ld long double15 #define inf 0x3f3f3f3f16 using namespace std;17 const int N=100010;18 int n,m,cnt; 19 ll a[N],d[100],res,ans;20 char gc(){21 static char*p1,*p2,s[1000000];22 if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);23 return(p1==p2)?EOF:*p1++;24 }25 ll rd(){26 ll x=0; char c=gc();27 while(c<'0'||c>'9')c=gc();28 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();29 return x;30 }31 void solve1(){32 Run(i,1,n){33 ll x=rd(); 34 ans|=x;35 } 36 printf("%llu",ans>>1);37 if(ans&1)printf(".5\n");38 else puts("");39 } 40 void solve2(){41 Run(i,1,n)a[i]=rd();42 for(int i=0;i<=32;i++)43 for(int j=0;j<=32;j++){44 int fg1=0,fg2=0,fg3=0;45 for(int k=1;k<=n;k++){46 if(a[k]>>i&1)fg1=1;47 if(a[k]>>j&1)fg2=1;48 if((a[k]>>i&1)!=(a[k]>>j&1))fg3=1; 49 if(fg1&&fg2&&fg3)break;50 }51 if(!fg1||!fg2)continue;52 if(i+j-fg3-1<0)res++;53 else ans+=1ull<<(i+j-fg3-1);54 }55 ans+=res>>1; res&=1;56 printf("%llu",ans);57 if(res)printf(".5\n");58 else puts("");59 }60 void solve3(){61 for(int i=1;i<=n;i++){62 ll x=rd();63 for(int j=63;~j;j--)if(x>>j&1){64 if(!d[j]){d[j]=x;break;}65 else x^=d[j];66 }67 } 68 for(int i=0;i<=63;i++)if(d[i])a[cnt++]=d[i];69 for(int i=0;i<1<
>j&1)x^=a[j];72 ll t1=0,t2=1;73 for(int j=1;j<=m;j++){74 t1*=x , t2*=x;75 t1 += t2 >> cnt , t2 &= (1<
> cnt , res &= (1<
View Code

 

转载于:https://www.cnblogs.com/Paul-Guderian/p/9899557.html

你可能感兴趣的文章
Have fun with Treasure Trails %enjoy 8% off cheap
查看>>
pdf转word如何转?最简单的方法你知道吗?
查看>>
“VR女友”制作人访谈
查看>>
阿列克谢·卡什巴斯基:有机生命渲染
查看>>
一文了解 Apache Flink 核心技术
查看>>
科略教育—管理者应具备五大能力
查看>>
mac上使用dex2jar遇到的权限问题的解决
查看>>
我的友情链接
查看>>
定位于地图小程序
查看>>
学习go语言 我的习题答案 chapter3
查看>>
vCenter Server Appliance 6.5 中重置丢失或忘记的 root 密码
查看>>
教育行业-班班通应用案例
查看>>
Linux SSH管理用户登录
查看>>
LAMP
查看>>
sendmail,mail,fetion,页面声音实现nagios报警
查看>>
硬链接和软连接
查看>>
nautilus can't be used now,due to an unexpected error解决方法
查看>>
《PHP经典实例(第二版)》(PHP Cookbook, 2nd Edition)中文版,高清扫描版[PDF]
查看>>
Spark On Yarn实战
查看>>
H3C设备与中兴89系列交换机snmp V3配置模板与kali snmpwalk配套测试
查看>>