xidian1006 n个数随机取l、r,分别求a[l]到a[r]的异或,与,非期望 :二进制/期望
考虑二进制的每个位
对于每个位可能哪些情况为1,仔细想想就出来了==
具体实现见代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define LL long long 5 using namespace std; 6 LL n,a[100005]; 7 double solve1() 8 { 9 double ans=0; 10 LL i,j,tmp,need0,need1; 11 for (j=0;j<30;j++) 12 { 13 tmp=(1<<j); 14 need1=need0=0; 15 for (i=1;i<=n;i++) 16 if (a[i]&(1<<j)) 17 { 18 ans+=2*need1*tmp; 19 ans+=tmp; 20 swap(need1,need0); 21 need0++; 22 } 23 else 24 { 25 ans+=2*need0*tmp; 26 need1++; 27 } 28 } 29 return ans/n/n; 30 } 31 double solve2() 32 { 33 double ans=0; 34 LL i,j,pre0,tmp; 35 for (j=0;j<30;j++) 36 { 37 tmp=(1<<j); 38 pre0=0; 39 for (i=1;i<=n;i++) 40 if (a[i]&(1<<j)) ans+=2*tmp*(i-pre0-1)+tmp; 41 else pre0=i; 42 } 43 return 1.0*ans/n/n; 44 } 45 double solve3() 46 { 47 double ans=0; 48 LL i,j,tmp,pre1; 49 for (j=0;j<30;j++) 50 { 51 tmp=(1<<j); 52 pre1=0; 53 for (i=1;i<=n;i++) 54 { 55 if (a[i]&(1<<j)) 56 { 57 ans+=2*(i-1)*tmp+tmp; 58 pre1=i; 59 } 60 else ans+=2*tmp*pre1; 61 } 62 } 63 return 1.0*ans/n/n; 64 } 65 int main() 66 { 67 LL i; 68 while (~scanf("%lld",&n)) 69 { 70 for (i=1;i<=n;i++) scanf("%lld",&a[i]); 71 printf("%.3lf %.3lf %.3lf\n",solve1(),solve2(),solve3()); 72 } 73 return 0; 74 } 75 76 /************************************************************** 77 Problem: 1006 78 User: xiaoxin 79 Language: C++ 80 Result: 正确 81 Time:145 ms 82 Memory:1864 kb 83 ****************************************************************/