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