[清华集训2014]玛里苟斯(线性基+概率期望)
2018-05-27 12:41
441 查看
首先有一些前置引理:
1. 由期望的线性性,平方的期望不等于期望的平方,所以求k次方的期望时,需要记录1~k-1的期望,然后计算增量(OSU!),这个这题没用上。
2. 线性基是可以变成每个元素都是2的次幂的(rebuild操作,也是求张成空间第k大的做法)。有一个关键的结论,张成空间内所有元素(设为k个)的出现概率都为$\frac{1}{2^k}$,也就是所有可能出现的异或和都是等概率的。
3. n个球里随机选,选到奇数个的概率和偶数个的概率各为1/2。观察杨辉三角可发现,偶数行由于对称显然成立,奇数行根据上一行得到所以也成立。(显然n=1除外)。
然后这题就可以做了。
首先k>=3时,可以知道x<=2^21,也就是张成空间最大为2^21,这个可以直接暴力搜索所有元素统计。
这里可能会爆unsigned long long,根据引理二发现分母是固定的,所以我们只要维护一个带分数(即一个整数和一个小于分母的分子)即可。
最后答案一定要么是整数,要么是.5。
当k=1时,根据引理三可知,如果有一位上所有数均为0,则这一位贡献为0,否则贡献为$\frac{1}{2}\times 2^x$,直接做即可。
当k=2时,将异或和每一位拆开来分情况讨论,这部分是较为复杂的。
基本上就像下面这样。
https://www.geek-share.com/detail/2735554520.html
#include<cstdio> #include<cstring> #include<algorithm> #define rep(i,l,r) for (int i=l; i<=r; i++) typedef unsigned long long ull; using namespace std; const int N=200010; int n,K,lp; ull p[66],x; struct P{ ull a[66]; int n; void insert(ull v){ for (int i=63;~i && v;i--) if ((v>>i)&1){ if (!a[i]) {a[i]=v; n++; break;} v^=a[i]; } } }b; void solve1(){ ull ans=0; for (int i=0;i<=63;i++){ bool flag=0; for (int j=0;j<=63;j++) if ((b.a[j]>>i)&1) flag=1; if (flag) ans+=1ll<<i; } printf("%llu",(ull)(ans/2)); if (ans&1) printf(".5"); } void solve2(){ ull ans=0,res=0; for (int i=0;i<=31;i++) for (int j=0;j<=31;j++){ bool c1,c2,c3,c4; c1=c2=c3=c4=0; for (int k=0;k<=31;k++){ if (((b.a[k]>>i)&1)==1 && ((b.a[k]>>j)&1)==1) c1=1; if (((b.a[k]>>i)&1)==1 && ((b.a[k]>>j)&1)==0) c2=1; if (((b.a[k]>>i)&1)==0 && ((b.a[k]>>j)&1)==1) c3=1; if (((b.a[k]>>i)&1)==0 && ((b.a[k]>>j)&1)==0) c4=1; } if (!(c1 || c3) || !(c1 || c2)) continue; if (!(c3 || c2)) if (i+j>0) ans+=(1ll<<(i+j-1)); else res+=2; else if (i+j>1) ans+=(1ll<<(i+j-2)); else res+=(1<<(i+j)); } printf("%llu",ans+(res>>2)); if (res&3) printf(".5"); } void solve3(){ for (int i=0;i<=63;i++) if (b.a[i]) p[lp++]=b.a[i]; ull ans=0,res=0; for (int i=0;i<(1<<lp);i++){ ull now=0,x=0,y=1; for (int j=0;j<lp;j++) if ((i>>j)&1) now^=p[j]; for (int j=0;j<K;j++) x*=now,y*=now,x+=y>>lp,y=y&((1<<lp)-1); res+=y; ans+=x; } printf("%llu",ans+(res>>lp)); if (res&((1<<lp)-1)) printf(".5"); } int main(){ freopen("bzoj3811.in","r",stdin); freopen("bzoj3811.out","w",stdout); scanf("%d%d",&n,&K); for (int i=1;i<=n;i++) scanf("%llu",&x),b.insert(x); if (K==1) solve1(); else if (K==2) solve2(); else solve3(); return 0; } bzoj3811
相关文章推荐
- 【清华集训2014】【BZOJ3811】玛里苟斯
- [UOJ]#36. 【清华集训2014】玛里苟斯
- 【BZOJ3811】【UOJ36】【清华集训2014】玛里苟斯
- BZOJ3811 玛里苟斯(线性基+概率期望)
- 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基
- 清华集训2014 day1 task1 玛里苟斯
- [清华集训2014]奇数国
- 【清华集训2014】mex
- 【XSY1287】【BZOJ3816】【清华集训2014】矩阵变换 稳定婚姻问题
- bzoj 3811: 玛里苟斯(期望+线性基)
- [BZOJ3585][清华集训2014]mex 主席树
- #46. 【清华集训2014】玄学
- JZOJ 3547【清华集训2014】mex
- 清华集训2014 day1 task2 主旋律
- jzoj3542 【清华集训2014】冒泡排序 (又是性质+半构造)
- 【树形期望DP】BZOJ3566- [SHOI2014]概率充电器
- 【jzoj3661】【SHTSC2014】【概率充电器】【期望】
- [BZOJ3566]-[SHOI2014]概率充电器-期望+树形dp
- uoj#38. 【清华集训2014】奇数国【欧拉函数】
- 【UOJ#38】【清华集训2014】奇数国