题意:
魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题。
S
S
S 是一个可重集合,
S
=
a
1
,
a
2
,
…
,
a
n
S={a1,a2,…,an}
S=a1,a2,…,an。
等概率随机取 S 的一个子集
A
=
a
i
1
,
…
,
a
i
m
A={ai1,…,aim}
A=ai1,…,aim。
计算出
A
A
A 中所有元素异或
x
x
x, 求
x
k
x^k
xk 的期望。
题解:
tyb
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL unsigned long long
using namespace std;
bool c[65];
LL n,k,a[100010],cnt=0;
LL b[65],t,a1=0,a2=0;
void dfs(LL x,LL v)
{
if(x>22)
{
if(k==3) a2+=v*v*v;
if(k==4)
{
a1+=(v*v/t)*v*v;
a1+=(v*v%t*v*v/t);
a2+=v*v%t*v%t*v%t;
}
if(k==5)
{
a1+=(v*v*v/t)*v*v;
a1+=(v*v*v%t*v*v/t);
a2+=v*v%t*v%t*v%t*v%t;
}
a1+=a2/t;a2%=t;
return;
}
dfs(x+1,v);
if(b[x]) dfs(x+1,v^b[x]);
}
LL ans=0;
int main()
{
scanf("%llu %llu",&n,&k);
memset(c,false,sizeof(c));
for(LL i=1;i<=n;i++) scanf("%llu",&a[i]);
for(LL i=1;i<=n;i++)
for(LL j=0;j<=63;j++) if(((LL)1<<j)&a[i]) c[j]=true;
if(k==1)
{
for(LL i=0;i<=63;i++) if(c[i]) ans+=(LL)1<<i;
printf("%llu",ans/2);
if(ans&1) printf(".5");
}
else if(k==2)
{
for(LL i=0;i<=63;i++)
if(c[i])
{
for(LL j=i+1;j<=63;j++)
if(c[j])
{
bool flag=true;
for(LL l=1;l<=n;l++)
if(((a[l]>>i)&1)!=((a[l]>>j)&1)) {flag=false;break;}
if(flag) ans+=(1LL<<(i+j+1));
else ans+=(1LL<<(i+j));
}
}
for(LL i=0;i<=63;i++) if(c[i]) ans+=(1LL<<(i*2));
printf("%llu",ans/2);
if(ans&1) printf(".5");
}
else
{
for(LL i=1;i<=n;i++)
{
LL x=a[i];
for(LL j=63;j>=0;j--)
{
if((1LL<<j)&x)
{
if(!b[j]) {b[j]=x;cnt++;break;}
x^=b[j];
}
if(j==0) break;
}
}
t=1LL<<cnt;dfs(0,0);
printf("%llu",a1);
if(a2) printf(".5");
}
}