3811: 玛里苟斯

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 190  Solved: 95
[Submit][Status][Discuss]

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

首先,对于题目的答案小于263,我们可以看出对于不同的k,ai是不同的:

k=1,ai<263
k=2,ai<232
k=3,ai<221
k=4,ai<216
k=5,ai<213

首先,因此我们依据数据范围,对于不同的ai有不同的解法。

其次,题目要求输出精确的小数,由以下推导我们可以知道,小数最多只有.5,不可能存在.25,.125这样的:

对于求出来了其中一种情况x,他对答案的贡献是xk*p,其中p是该情况出现的概率。
我们以x=2为例,其他k的情况类似:
我们把这个x按二进制分成了最多n位,也就是最大的数的最高位为n。那么他的k次方是(w0*20+w1*21+w2*22……+wn*2n)*(w0*20+w1*21+w2*22……+wn*2n),展开就是w0*w0*20*20+w0*w1*20*21……wn*wn*2n*2n。其中wi是它每个二进制位的值。
对于每个项wi*wj*2i+j,他存在的情况是wi为1且wj为1,也就是该位异或和为1。那么他的存在的概率为P/2N(N为输入的数列数字数),P为该两位皆为1的情况数。
证明题外话:对于数列,我们可以先做个线性基,把线性相关的数字去掉,剩下的都是线性无关的数,这样方便处理。
我们可以构造一个异或(%2)的增广矩阵来求解这样的一个P的数量,x1~xn,即xi代表这个数字是否在集合中,作为一个行向量X,把所有数字按按二进制位分解,每个数字占一列,构造一个矩阵MART.
那么我们求解的是X*MART=ANS,ANS为一个行向量,只有你要求的对应位为1,其余为0。
假如我们求解的是i位和j位,我们的矩阵对应方程差不多是这样的:
(2333 此处^为异或)
x1*w(1,0)^x2*w(2,0)^x3*w(3,0) ……^xN*w(N,0) =0;
x1*w(1,1)^x2*w(2,1)^x3*w(3,1) ……^xN*w(N,1) =0;
……
x1*w(1,i)^x2*w(2,i)^x3*w(3,i) ……^xN*w(N,i) =1;
……
x1*w(1,j)^x2*w(2,j)^x3*w(3,j) ……^xN*w(N,j) =1;
……
x1*w(1,n)^x2*w(2,n)^x3*w(3,n) ……^xN*w(N,n) =0;
下面还有N-n个方程,对应更高位。毕竟是个矩阵嘛行数等于列数,但它们的w全为0,等号右边也为0,对求解无影响就不列举了。

其中w(i,j),j代表数列第i个数字的第j位。
我们经过高斯消元以后弄成上三角,可以得出有t个f[i][i]非零的行,那么只有这t个xi是有唯一解的,其他的xi有多解。因为%2,所以其他xi有2解,那么总共就有2N-t个解,即P=2N-t;
那么wi*wj存在的概率为p/2N=1/(2t);
那么每项对答案的贡献为2i+j-t
对于i≠j,i+j≥1,t≤2,因此最多小数点后1位.5。
对于i==j,上述方程只有一行初始为1,所以t≤1,i+j≥0,也是最多.5。
上述结论扩展成k=n的情况,无非是方程等于1的行增加为n。
如果我们求解的位(wi*wj*wt.....)中有k位不同,那么方程等于1的行就缩小为k行,因此i+j+t....≥0+1+……k-1=k*(k-1)/2>=k-1=t-1,k≥2。
∴Σp-t>=-1,p为所求解对应位的位号。对应k=2的贡献2i+j-t,K=n贡献为2Σp-t>=2-1。所以最多有一位小数.5。
k=1显而易见最多/2所以k=1也是最多也是.5。
至此证明完毕。

接下来我们对应数据范围,提出三种不同范围下的解法:

k=1时,就求x的期望,它是线性的。对于所有数的所有子集的异或和,我们从他们某个二进制位看。如果有数字该位为1,那么该位有奇数个1和偶数个1的概率是相等的,皆为1/2。为奇数个为该位为1的情况,为1/2。如果没有则不可能为1,该位始终为0。
那么我们只要把每个数字或一下,然后乘1/2就是答案了。

k=2时,就要按位做了。先做个线性基剔除线性无关的向量。然后把在线性基每位唯一化(即消消元弄成每位上只有一个数字有1),这样做方便处理独立性。按照上面证明的展开,那么对于两位i,j,由k=1可得,如果这两位独立的话(即不在同一个数字中相应位为1),那么等概率出现(0,0),(0,1),(1,0),(1,1),(1,1)即wi,wj存在的概率为1/4,不独立的话只可能等概率出现(0,0)和(1,1),(1,1)概率为1/2。
那么枚举32位*32位,算算他们均为1的概率P*2i+j,作为答案贡献加入答案中。

k≥3时,由于ai<221 ,即使枚举0~ai也最多百万级别的时间复杂度。我们可以类似线性基求第k小枚举出所有可能出现的数字。于是我们可以考虑做完线性基后,唯一化,构造新数组存不为0的元素中。
然后枚举每个数是否加入异或贡献中,这样可以求出所有数异或的所有值了。借用之前题目的结论,每个不同的异或值有P=2n-|μ|选择元素的方法,n为原本数组个数,|μ|为新构造的数组个数。那么每个值出现的概率就是P/总选择方法数=P/(2n)=1/(2|μ|)的概率,值 乘 概率即为对答案的贡献。
这里需要做个两位的高精来保证数字不出现错误。

  1 #include<bits/stdc++.h>
  2 #define clr(x) memset(x,0,sizeof(x))
  3 #define clr_1(x) memset(x,-1,sizeof(x))
  4 #define LL unsigned long long
  5 #define mod 1000000007
  6 using namespace std;
  7 const int N=2e5+10;
  8 LL a[N],liner[100],per[100];
  9 bool f[40][40];
 10 bool bits[40];
 11 int n,m,k,cnt;
 12 LL ans,res,keepbit;
 13 void calc(int bit)
 14 {
 15     clr(liner);
 16     LL p;
 17     for(int i=1;i<=n;i++)
 18     {
 19         for(int j=bit;j>=0;j--)
 20         {
 21             p=a[i];
 22             if(p>>j)
 23             {
 24                 if(liner[j]) p^=liner[j];
 25                 else
 26                 {
 27                     liner[j]=p;
 28                     break;
 29                 }
 30             }
 31         }
 32     }
 33     for(int i=bit;i>=0;i--)
 34     {
 35         for(int j=i-1;j>=0;j--)
 36             if((liner[i]>>j)&1) liner[j]^=liner[i];
 37     }
 38     cnt=0;
 39     for(int i=bit;i>=0;i--)
 40         if(liner[i])
 41             per[++cnt]=liner[i];
 42     return ;
 43 }
 44 void solve1(int n)
 45 {
 46     ans=0,res=0;
 47     for(int i=1;i<=n;i++)
 48         ans|=a[i];
 49     if(ans&1)
 50         res=1;
 51     ans>>=1;
 52     return ;
 53 }
 54 void solve2(int n)
 55 {
 56     clr(bits);
 57     ans=res=0;
 58     bool zero;
 59     for(int i=32;i>=0;i--)
 60     {
 61         zero=0;
 62         for(int j=1;j<=cnt;j++)
 63         {
 64             f[i][j]=(per[j]>>i)&1;
 65             zero|=f[i][j];
 66         }
 67         bits[i]=zero;
 68     }
 69     int p;
 70     for(int i=32;i>=0;i--)
 71         for(int j=32;j>=0;j--)
 72             if(bits[i]>0 && bits[j]>0)
 73             {
 74                 p=1;
 75                 for(int l=1;l<=cnt;l++)
 76                     if(f[i][l]^f[j][l])
 77                     {
 78                         p++;
 79                         break;
 80                     }
 81                 if(i+j-p>=0)
 82                     ans+=(1LL<<(i+j-p));
 83                 else
 84                 {
 85                     res++;
 86                 }
 87                 ans+=res>>1;
 88                 res&=1;
 89             }
 90     return ;
 91 }
 92
 93 void dfs(int pos,LL num)
 94 {
 95
 96     if(pos>cnt)
 97     {
 98         //两位高精度计算u高位,v低位,因为这东西太大了。k>=3的情况下ans和res也算是一个高精度的高位和低位关系。
 99         LL u=0,v=1;
100         for(int i=1;i<=k;i++)
101         {
102             u*=num;
103             v*=num;
104             u+=v>>cnt;
105             v&=keepbit;
106         }
107         ans+=u;
108         res+=v;
109         ans+=res>>cnt;
110         res&=keepbit;
111         return ;
112     }
113     dfs(pos+1,num^per[pos]);
114     dfs(pos+1,num);
115     return ;
116 }
117 void solve3(int n,int k)
118 {
119     ans=0;
120     res=0;
121     keepbit=(1LL<<cnt)-1;
122     dfs(1,0);
123     return ;
124 }
125 int main()
126 {
127     scanf("%d%d",&n,&k);
128     for(int i=1;i<=n;i++)
129         scanf("%llu",&a[i]);
130     if(k==1)
131         solve1(n);
132     else if(k==2)
133     {
134         calc(32);
135         solve2(n);
136     }
137     else
138     {
139         calc(61/k+1);
140         solve3(n,k);
141     }
142     printf("%llu",ans);
143     if(res) printf(".5");
144     printf("\n");
145     return 0;
146 }

View Code

转载于:https://www.cnblogs.com/wujiechao/p/7781140.html

bzoj 3811: 玛里苟斯相关推荐

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

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

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

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

  3. [BZOJ 3811]玛里苟斯(线性基)尽量理解的题解

    文章目录 title solution code title 魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题. S 是一个可重集合,S={a1,a2,-,an}. 等概率随 ...

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

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

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

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

  6. 线性基(bzoj 2460: [BeiJing2011]元素)

    线性基: 包含最多h个数(a1, a2, a3, -, ah),其中ak如果存在,那么最高位一定是第k位 性质①:线性基中任意集合xor出来的数的值域 = 原数列任意集合xor出的数的值域 性质②:线 ...

  7. 从我的游戏成瘾中恢复

    重点 (Top highlight) I can play a video game for just an hour these days and then stop. I have no prob ...

  8. 自行车改装电动车怎么样_电动车听起来应该是什么样?

    自行车改装电动车怎么样 The sound of an all-electric car accelerating doesn't have to sound like a standard comb ...

  9. 【清华集训 2014】玛里苟斯(组合计数 + 线性基)

    题目链接:[清华集训 2014]玛里苟斯 推荐博客:[BZOJ 3811]玛里苟斯:线性基(详细证明) 首先想到将kkk分类讨论. k=1" role="presentation& ...

最新文章

  1. 阿里程序员回老家被哥们问工作,回答在阿里,哥们却吐槽:破IT就破IT,还阿里巴巴!网友:京东就是送快递的,美团就是送外卖的!...
  2. 论 MySql InnoDB 如何通过插入意向锁控制并发插入
  3. Linux中的DRM、DRI、DMA 介绍
  4. 从零开始一步一步搭建Ubuntu Server服务器、修改数据源、安装Docker、配置镜像加速器、Compose部署Gitlab服务
  5. wxWidgets:使用 wxWidgets 资源文件XRC
  6. Python设计模式之外观模式实例讲解
  7. Electron - 创建跨平台的桌面客户的应用程序
  8. 【Spark Summit East 2017】使用Spark MLlib和Apache Solr构建实时实体类型识别系统
  9. Mycat安全权限配置privileges---MyCat分布式数据库集群架构工作笔记0032
  10. 什么才是一份好的AI求职简历?
  11. 网格分割后,边界点的获取方法
  12. UISlider 设置增量
  13. Python游戏汇总:三十个pygame游戏代码【附源码免费分享】
  14. 粗浅看Struts2和Hibernate框架
  15. XP系统的的一些快捷方式
  16. 鸿蒙杀戮手机电脑版,鸿蒙杀戮单职业
  17. 遗传算法解决城市TSP问题
  18. 开学啦!来淘宝教育体验开学第一课
  19. Linux系统下如何复制粘贴
  20. 最全面试宝典-我的春招总结

热门文章

  1. linux引导记录重新安装
  2. Comment obtenir des vecteurs de phrases?
  3. 在Linux服务器上如何开启安全的SNMP代理
  4. 2022-2028全球与中国颈挂式蓝牙耳机市场现状及未来发展趋势
  5. 如何用 Photoshop 做出这种迷幻效果?
  6. 蛮力法(python)
  7. Python爬虫入门教程 24-100 微医挂号网医生数据抓取
  8. yum操作提示错误:There are no enabled repos.
  9. C语言统计数字出现的次数
  10. Python编程:从入门到实践pdf