题目
分析
首先位运算没有进位,这样可以让它一位一位进行,如题所述,设表示的第位,当的时候概率为,然后当时数学期望为。
Then,当时,概率为,对于,找到前面最后一个0的位置,那么可选的的个数,为。
对于,当为1,时为任何数,否则个数为最后一个1的位置
对于,当为1时就会改变个数,所以说每遇到的时候个数肯定是会交换的,具体就不多解释
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int n,a[100001]; double sxor,sand,suor;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
inline void answ(int k){
rr int p0=0,p1=0,c1=0,c2=0;
for (rr int i=1;i<=n;++i)
if ((a[i]>>k)&1){
sxor+=(1<<k)*1.0/n/n;
sand+=(1<<k)*1.0/n/n;
suor+=(1<<k)*1.0/n/n;
sand+=(1<<k)*2.0/n/n*(i-1-p0);
suor+=(1<<k)*2.0/n/n*(i-1);
sxor+=(1<<k)*2.0/n/n*c1;
++c1; c1^=c2,c2^=c1,c1^=c2; p1=i;
}
else{
suor+=(1<<k)*2.0/n/n*p1;
sxor+=(1<<k)*2.0/n/n*c2;
++c1; p0=i;
}
}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=0;i<30;++i) answ(i);
printf("%.3lf %.3lf %.3lf",sxor,sand,suor);
return 0;
}