21.09.12模擬 友誼值
阿新 • • 發佈:2021-10-07
給定n個數,要求求出兩兩異或值的和。位運算位與位之間是相互獨立的,我們可以拆位來處理。對於第i位,顯然只有0與1,1與0異或後有貢獻答案 1<<i ,O(n)解決
#include<iostream> #include<cmath> #include<cstdio> #define rep(i,j,k) for(register int i(j);i<=k;++i) #define drp(i,j,k) for(register int i(j);i>=k;--i) #define bug cout<<"~~~~~~~~~~~~~"<<'\n'; #define bugout(x) out(x,'\n'); typedef long long lxl; template<typename T> inline T max(T &a, T &b) { return a > b ? a : b; } template<typename T> inline T min(T &a, T &b) { return a < b ? a : b; } inline char gt() { static char buf[1 << 21], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++; } template <typename T> inline void read(T &x) { register char ch = gt(); x = 0; int w(0); while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt(); while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt(); w ? x = ~(x - 1) : x; } template <typename T> inline void out(T x, char cc) { if(x < 0) x = -x, putchar('-'); char ch[20]; int num(0); while(x || !num) ch[++num] = x % 10 + '0', x /= 10; while(num) putchar(ch[num--]); putchar(cc); } const int N = 1e6 + 79; int n; int a[N]; lxl ans; int bit[57]; int main() { freopen("friendship.in", "r", stdin); freopen("friendship.out", "w", stdout); read(n); rep(i, 1, n) { read(a[i]); rep(j, 0, 23) { if(a[i] & (1 << j)) { bit[j]++;//統計第j位為1的數字的個數 } } } rep(j, 0, 23) { ans += 1ll * bit[j] * (n - bit[j]) * (1ll << j);//第j位為0與1搭配的對數 } out(ans, '\n'); return 0; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15375989.html