3811: 玛里苟斯

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 500  Solved: 196
[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

HINT

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

Source

[Submit][Status][Discuss]

题解:
        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最小的情况:
分析可以发现最小为-;
所以答案小数点后只有一位; 。。。。。。

如果你感兴趣的话

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

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<stack>
#include<map>
#include<set>
#define Run(i,l,r) for(int i=l;i<=r;i++)
#define Don(i,l,r) for(int i=l;i>=r;i--)
#define ll unsigned long long
#define ld long double
#define inf 0x3f3f3f3f
using namespace std;
const int N=;
int n,m,cnt;
ll a[N],d[],res,ans;
char gc(){
static char*p1,*p2,s[];
if(p1==p2)p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
ll rd(){
ll x=; char c=gc();
while(c<''||c>'')c=gc();
while(c>=''&&c<='')x=(x<<)+(x<<)+c-'',c=gc();
return x;
}
void solve1(){
Run(i,,n){
ll x=rd();
ans|=x;
}
printf("%llu",ans>>);
if(ans&)printf(".5\n");
else puts("");
}
void solve2(){
Run(i,,n)a[i]=rd();
for(int i=;i<=;i++)
for(int j=;j<=;j++){
int fg1=,fg2=,fg3=;
for(int k=;k<=n;k++){
if(a[k]>>i&)fg1=;
if(a[k]>>j&)fg2=;
if((a[k]>>i&)!=(a[k]>>j&))fg3=;
if(fg1&&fg2&&fg3)break;
}
if(!fg1||!fg2)continue;
if(i+j-fg3-<)res++;
else ans+=1ull<<(i+j-fg3-);
}
ans+=res>>; res&=;
printf("%llu",ans);
if(res)printf(".5\n");
else puts("");
}
void solve3(){
for(int i=;i<=n;i++){
ll x=rd();
for(int j=;~j;j--)if(x>>j&){
if(!d[j]){d[j]=x;break;}
else x^=d[j];
}
}
for(int i=;i<=;i++)if(d[i])a[cnt++]=d[i];
for(int i=;i<<<cnt;i++){
ll x=;
for(int j=;j<cnt;j++)if(i>>j&)x^=a[j];
ll t1=,t2=;
for(int j=;j<=m;j++){
t1*=x , t2*=x;
t1 += t2 >> cnt , t2 &= (<<cnt) - ;
}
ans += t1 , res += t2;
ans += res >> cnt , res &= (<<cnt) - ;
}
printf("%llu",ans);
if(res)printf(".5\n");
else printf("\n");
}
int main(){
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
n=rd(); m=rd();
if(m==)solve1();
else if(m==)solve2();
else solve3();
return ;
}//by tkys_Austin;

【bzoj3811】【清华集训2014】玛里苟斯的更多相关文章

  1. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  2. AC日记——【清华集训2014】奇数国 uoj 38

    #38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...

  3. UOJ#46. 【清华集训2014】玄学

    传送门 分析 清华集训真的不是人做的啊嘤嘤嘤 我们可以考虑按操作时间把每个操作存进线段树里 如果现在点x正好使一个整块区间的右端点则更新代表这个区间的点 我们不难发现一个区间会因为不同的操作被分成若干 ...

  4. 清华集训2014 sum

    清华集训2014sum 求\[∑_{i=1}^{n}(-1)^{⌊i√r⌋}\] 多组询问,\(n\leq 10^9,t\leq 10^4, r\leq 10^4\). 吼题解啊 具体已经讲得很详细了 ...

  5. 清华集训2014 day1 task1 玛里苟斯

    题目 这可算是描述很简单的一道题了!但是不简单. \(S\)是一个可重集合,\(S = \{a_1, a_2, \dots, a_n \}\). 等概率随机取\(S\)的一个子集\(A = \{a_{ ...

  6. [UOJ]#36. 【清华集训2014】玛里苟斯

    题目大意:给n个数字,求子集的异或和的k次方的期望(n<=10^5,k<=5,保证答案小于2^63) 做法:首先如果从集合中拿出a和b,把a和a xor b放回集合,子集的异或和与原来是一 ...

  7. UOJ#36. 【清华集训2014】玛里苟斯 线性基

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ36.html 题解 按照 $k$ 分类讨论: k=1 : 我们考虑每一位的贡献.若有至少一个数第 $i$ ...

  8. UOJ #36「清华集训2014」玛里苟斯

    这怎么想得到啊......... UOJ #36 题意:求随机一个集合的子集的异或和的$k$次方的期望值,保证答案$ \lt 2^{63},1 \leq k \leq 5$ $ Solution:$ ...

  9. uoj#36. 【清华集训2014】玛里苟斯(线性基+概率期望)

    传送门 为啥在我看来完全不知道为什么的在大佬们看来全都是显然-- 考虑\(k=1\)的情况,如果序列中有某一个\(a_j\)的第\(i\)位为\(1\),那么\(x\)的第\(i\)位为\(1\)的概 ...

随机推荐

  1. win7升级到win10,出现算术运算溢出问题

    前台winform,后台java代码是: OutputStream ou=(OutputStream)response.getOutputStream(); ou.write(rightSet.get ...

  2. 180716-Centos时区设置

    使用timedatectl命令同步时间并设置时区 I. timedatactl命令 1. 使用帮助 timedatectl -h 2. 命令示例 2.1 显示系统的当前时间和日期 timedatect ...

  3. Appium+python的单元测试框架unittest(4)——断言(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10051576.html) 在我们编写的测试用例中,测试步骤和预期结果是必不可少的.当我们运行测试用例时,得到一个运行 ...

  4. 001 -js对时间日期的排序

    001-JS对时间日期的排序 最近在做公司的项目时间,产品给了一个很简单的页面,让帮忙写一下.首先看一下产品的需求: 需要对该列表进行排序 思路:(1)可以在数据库写sql语句的时间直接一个DESC按 ...

  5. 169.求众数 leetcode Javascript

    给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] 输出: 3 ...

  6. Python基础灬函数(定义,参数)

    函数 函数定义 # 定义一个计算绝对值的函数 def cal_abs(x): if x >= 0: return x else: return -x # 调用函数 print('-1的绝对值是: ...

  7. 【RL系列】On-Policy与Off-Policy

    强化学习大致上可分为两类,一类是Markov Decision Learning,另一类是与之相对的Model Free Learning 分为这两类是站在问题描述的角度上考虑的.同样在解决方案上存在 ...

  8. C#判断字符串中是否有数字

    // <summary> /// 提取字符串中的数字字符串 /// </summary> /// <param name="str"></ ...

  9. AutoCAD 自动管理字体插件[使用ObjectARX C++]

    概述: 使用AutoCAD的过程中,我们常常因为缺失字体而烦恼,本插件就是为了解决这个问题. 插件采用WEB服务器 + CAD插件方式.WEB服务器使用Python编写,部署在百度BAE上:CAD插件 ...

  10. MySQL 中的数据类型介绍

    1.MySQL 数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 2.数值类型(12) 2.1. ...