1. 程式人生 > 實用技巧 >CF 1368D AND, OR and square sum

CF 1368D AND, OR and square sum

傳送門

題目:

Gottfried learned about binary number representation. He then came up with this task and presented it to you.

You are given a collection ofnnnon-negative integersa1,…,an. You are allowed to perform the following operation: choose two distinct indices1≤i,j≤n. If before the operationai=x,aj=y, then after the operationai=xANDy,aj=xORy, whereANDandORare bitwise AND and OR respectively (refer to the Notes section for formal description). The operation may be performed any number of times (possibly zero).

After all operations are done, compute∑(i=1n)ai^2— the sum of squares of allai. What is the largest sum of squares you can achieve?

思路:x + y = x | y + x & y,ai = x | y, bi = x & y,可以看出總價值不變,只是把y可給x利用的價值加上,然後y減去被利用的價值,而二進位制中利用的都是不同權值上的1,說明二進位制上1的個數不變,只是在於轉移給其他二進位制串,這樣我們可以統計所有權值的二進位制位為1,然後構造出還能構造出的最大的二進位制即可(x^2 + y^2 <= (x + y) ^ 2 , x,y>=0).

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <queue>
 5 #include <string>
 6 #include <vector>
 7 #include <cmath>
 8 #include <stack> 
 9  
10 using namespace std;
11  
12 #define ll long long
13 #define pb push_back
14
#define fi first 15 #define se second 16 17 const int N = 2e5 + 10; 18 int bit[N]; 19 int a[N]; 20 21 void solve() 22 { 23 int n; 24 cin >> n; 25 for(int i = 1; i <= n; ++i) cin >> a[i]; 26 for(int i = 1; i <= n; ++i){ 27 for(int b = 0; b <= 25; ++b){ 28 if(a[i] & (1 << b)) bit[b]++; 29 } 30 } 31 32 ll ans = 0; 33 for(int i = 1; i <= n; ++i){ 34 int num = 0; 35 for(int b = 30; b >= 0; --b){ 36 if(bit[b]){ 37 num += (1 << b); 38 bit[b]--; 39 } 40 } 41 ans += (ll)num * num; 42 } 43 //cout << "ans = "; 44 cout << ans << endl; 45 } 46 47 int main() 48 { 49 ios::sync_with_stdio(false); 50 cin.tie(0); 51 cout.tie(0); 52 solve(); 53 54 return 0; 55 } 56 57 // 10101010101010101010 58 // 01010101010101010101 59 // 111