题解:概率计数。因为是求期望值,考虑每个点对答案的贡献:对每个点是亮着的概率求和就是所求期望。
那么每个点亮着的概率为多少呢?根据题意,对于点(x,y,z)只有当被选中的2个点(x1,y1,z1),(x2,y2,z2),
满足x1<=x<=x2且y1<=y<=y2且z1<=z<=z2时,该点的状态才会改变,因此对于每一维,
在区间内的概率=1-区间在该点的同一侧的概率
该点状态会改变的概率p=x维在区间内的概率*y维在区间内的概率*z维在区间内的概率
上述的只是状态改变一次的概率,题目中说会选择k次区间,根据异或原理,在这k次中,如果状态改变的次数为奇数次,那么该点最终是亮着的。
设f(x)为选择x次区间时,状态改变次数为奇数的概率,g(x)为状态改变次数为偶数的概率。
f(x)=(1-p)*f(x-1)+p*g(x-1)
g(x)=(1-p)*g(x-1)+p*f(x-1)
f(x)+g(x)=1
因此f(x)=(1-2p)*f(x-1)+p,两边同时除以(1-2p)^x,再化简成等比数列通项公式f(x)=0.5-0.5*(1-2p)^x
#include<bits/stdc++.h>
using namespace std;
#define ll long long
double cul(int a, int b) {
//求在某一维,两个点不在同一侧的概率
return 1.0 - 1.0 * ((a - 1) * (a - 1) + (b - a) * (b - a)) / (b * b);
}
int main()
{
int t,x,y,z,n,oo=0;
double a,q;
scanf("%d",&t);
while(t--)
{
double ans=0;
scanf("%d%d%d%d",&x,&y,&z,&n);
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
for(int k=1;k<=z;k++)
{
a=cul(i,x)*cul(j,y)*cul(k,z);
ans += 0.5 - 0.5 * pow(1 - 2 * a, 1.0 * n);//被覆盖奇数次的概率
}
}
}
printf("Case %d: %.7lf\n",++oo,ans);
}
}