SPOJ - BITDIFF: Bit Difference [神妙の预处理]

tags:[数学][预处理]
题解:
我们用一种巧妙的预处理姿势:记录下每一个数位上分别出现了多少个1。
如果第i个数位上出现了cnt[i]个1,那么,在这个数位上产生的“差异值”
为:2*cnt[i]*(n-cnt[i])。sigma (2*cnt[i]*(n-cnt[i])) 即为最终答案。
同类题:
1. 给n个数字,求所有数对异或值之和。[n<=100000]
2. CF766E [在树上这种预处理姿势]

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int MOD = 10000007;
int T, n, x, Time = 0;
int cnt[40];
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        memset(cnt, 0, sizeof(cnt));
        for(int i=1;i<=n;i++)
        {
            scanf("%d", &x);
            int tmp = 0;
            while(x)
            {
                tmp ++;
                if(x & 1) 
                {
                    cnt[tmp] ++;
                }
                x /= 2;
            }
        }
        int res = 0;
        for(int i=1;i<40;i++)
        {
            res += cnt[i] * (n - cnt[i]);
            res %= MOD;
        }
        res = 2 * res % MOD;
        printf("Case %d: %d\n", (++Time), res);
    }
}

  

posted @ 2017-02-12 01:00  RUSH_D_CAT  阅读(163)  评论(0编辑  收藏  举报