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|μ|)的概率,值 乘 概率即为对答案的贡献。
这里需要做个两位的高精来保证数字不出现错误。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define LL unsigned long long
#define mod 1000000007
using namespace std;
const int N=2e5+;
LL a[N],liner[],per[];
bool f[][];
bool bits[];
int n,m,k,cnt;
LL ans,res,keepbit;
void calc(int bit)
{
clr(liner);
LL p;
for(int i=;i<=n;i++)
{
for(int j=bit;j>=;j--)
{
p=a[i];
if(p>>j)
{
if(liner[j]) p^=liner[j];
else
{
liner[j]=p;
break;
}
}
}
}
for(int i=bit;i>=;i--)
{
for(int j=i-;j>=;j--)
if((liner[i]>>j)&) liner[j]^=liner[i];
}
cnt=;
for(int i=bit;i>=;i--)
if(liner[i])
per[++cnt]=liner[i];
return ;
}
void solve1(int n)
{
ans=,res=;
for(int i=;i<=n;i++)
ans|=a[i];
if(ans&)
res=;
ans>>=;
return ;
}
void solve2(int n)
{
clr(bits);
ans=res=;
bool zero;
for(int i=;i>=;i--)
{
zero=;
for(int j=;j<=cnt;j++)
{
f[i][j]=(per[j]>>i)&;
zero|=f[i][j];
}
bits[i]=zero;
}
int p;
for(int i=;i>=;i--)
for(int j=;j>=;j--)
if(bits[i]> && bits[j]>)
{
p=;
for(int l=;l<=cnt;l++)
if(f[i][l]^f[j][l])
{
p++;
break;
}
if(i+j-p>=)
ans+=(1LL<<(i+j-p));
else
{
res++;
}
ans+=res>>;
res&=;
}
return ;
} void dfs(int pos,LL num)
{ if(pos>cnt)
{
//两位高精度计算u高位,v低位,因为这东西太大了。k>=3的情况下ans和res也算是一个高精度的高位和低位关系。
LL u=,v=;
for(int i=;i<=k;i++)
{
u*=num;
v*=num;
u+=v>>cnt;
v&=keepbit;
}
ans+=u;
res+=v;
ans+=res>>cnt;
res&=keepbit;
return ;
}
dfs(pos+,num^per[pos]);
dfs(pos+,num);
return ;
}
void solve3(int n,int k)
{
ans=;
res=;
keepbit=(1LL<<cnt)-;
dfs(,);
return ;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
scanf("%llu",&a[i]);
if(k==)
solve1(n);
else if(k==)
{
calc();
solve2(n);
}
else
{
calc(/k+);
solve3(n,k);
}
printf("%llu",ans);
if(res) printf(".5");
printf("\n");
return ;
}

bzoj 3811: 玛里苟斯的更多相关文章

  1. BZOJ.3811.玛里苟斯(线性基)

    BZOJ UOJ 感觉网上大部分题解对我这种数学基础差的人来说十分不友好...(虽然理解后也觉得没有那么难) 结合两篇写的比较好的详细写一写.如果有错要指出啊QAQ https://blog.csdn ...

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

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

  3. 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基

    大力观察:I.从输出精准位数的约束来观察,一定会有猫腻,然后仔细想一想,就会发现输出的时候小数点后面不是.5就是没有 II.从最后答案小于2^63可以看出当k大于等于3的时候就可以直接搜索了 期望概率 ...

  4. 【bzoj3811】【清华集训2014】玛里苟斯

    3811: 玛里苟斯 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 500  Solved: 196[Submit][Status][Discuss] ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. 【BZOJ3811】玛里苟斯(线性基)

    [BZOJ3811]玛里苟斯(线性基) 题面 BZOJ 题解 \(K=1\)很容易吧,拆位考虑贡献,所有存在的位出现的概率都是\(0.5\),所以答案就是所有数或起来的结果除二. \(K=2\)的情况 ...

  7. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  8. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  9. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

随机推荐

  1. Linux磁盘分区、挂载

    ⒈Linux下磁盘说明 1)Linux硬盘分IDE硬盘和SCSI硬盘,目前基本上是SCSI硬盘. 2)对于IDE硬盘,使用“hdx~”标识符,“hd”代表IDE硬盘.   对于SCSI硬盘,使用“sd ...

  2. python内置模块之collections(六)

    前言 collections是Python内建的一个集合模块,提供了许多有用的集合类. 系列文章 python模块分析之random(一) python模块分析之hashlib加密(二) python ...

  3. python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib

    python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multib ...

  4. [转] bss段、data段、text段

    1.前言 一个程序本质上都是由 BSS 段.DATA段.TEXT段三个组成的. 本文主要分编译时和运行时分别对 对data段 bss段 text段 堆 栈作一简要说明 2. 程序编译时概念说明 程序与 ...

  5. WebsphereMQ搭建集群

    #https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1202_gaoly_mq/1202_gaoly_mq.ht ...

  6. 生产环境elasticsearch5.0.1和6.3.2集群的部署配置详解

    线上环境elasticsearch5.0.1集群的配置部署 es集群的规划: 硬件: 7台8核.64G内存.2T ssd硬盘加1台8核16G的阿里云服务器 其中一台作为kibana+kafka连接查询 ...

  7. Go语言规格说明书 之 Go语句(Go statements)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  8. Python-CSS进阶

    0. 什么时候该用什么布局 <!-- 定位布局: 以下两种布局不易解决的问题, 盒子需要脱离文档流处理 --> <!-- 浮动布局: 一般有block特性的盒子,水平排列显示 --& ...

  9. 目标检测的图像特征提取之(一)HOG特征(转)

    看过很多介绍HOG的博文,讲的最清楚的是这位博主:http://blog.csdn.net/zouxy09/article/details/7929348 代码如下: #include <ope ...

  10. php和NodeJs共存的开发环境

    1 折腾 php nodejs 到一起 nodejs当然很火,就像着火了一样,但是必须承认要搭建一个前端的demo开发环境还是PHP靠谱, windows下可以非常的集成套件,比如http://www ...