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);
}
}

浙公网安备 33010602011771号