题目:http://acm.uestc.edu.cn/problem.php?pid=1709
View Code
#include <stdio.h> #include <string.h> #include <iostream> #define ll long long using namespace std; const int N = 50000+10; int M; ll a[N], n, dp[N], m; ll get_and(int y){ ll ans = 0; dp[0]=0; for (int i=1; i<=n; i++){ if ((a[i]&(1<<y)))dp[i]=dp[i-1]+1; else dp[i]=0; ans += dp[i]; } return ans << y; } ll get_or(int y){ ll ans = 0; dp[0]=0; for (int i=1; i<=n; i++){ if ((a[i]&(1<<y)))dp[i]=i; else dp[i]=dp[i-1]; ans += dp[i]; } return ans << y; } ll get_xor(int y){ ll ans=0; dp[0]=0; for (int i=1; i<=n; i++){ if ((a[i]&(1<<y)))dp[i]=i-dp[i-1]; else dp[i]=dp[i-1]; ans += dp[i]; } return ans << y; } void solve(int k){ ll ans = 0; if (k==1){ for (int i=0; i<=M; i++){ ans += get_and(i); } } else if (k==2){ for (int i=0; i<=M; i++){ ans += get_or(i); } } else { for (int i=0; i<=M; i++){ ans += get_xor(i); } } double t = ans*2.0 / (n*(n+1)); printf(" %.6f", t); } int main() { //freopen("D:/a.txt", "r", stdin); int T, cas=1; scanf("%lld", &T); while (T--){ m = -1; scanf("%lld", &n); for (int i=1; i<=n; i++) scanf("%lld", &a[i]), m=max(m, a[i]); for (int i=0; i<31; i++) if(m&(1<<i)) M=i; printf("Case #%d:", cas++); for (int i=1; i<=3; i++) solve(i); puts(""); } return 0; }