博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[uestc][1709][Binary Operations]

Posted on 2012-07-11 18:32  紫华弦筝  阅读(161)  评论(0编辑  收藏  举报

题目: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;
}