[] Good luck bit computing

Good luck

Given \ (n \) integers, followed by \ (a_1, a_2, ..., a_n. \)

Seeking \ (\ sum_. 1} ^ {n-I = \ sum_. 1} = {J ^ n-(a_i \ & a_j) \) . \ (\ & \) Is the binary operator

Easy to think of dual circulation

for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
		ans+=(a[i]&a[j]);

Time complexity is \ (O (^ n-2) \) , and \ (n-<= 10. 5 ^ \) , timed out.

Given the nature and operation: each number is converted into a binary number, and then a calculation for one. Only when the two numbers are the result only when 1 is 1, otherwise the results are zero.

To sample, for example, five numbers into binary numbers get

\(00001\)

\(00010\)

\(00011\)

\(00100\)

\(00101\)

For the rightmost column, in \ (a [1] \) when ANDed with other numbers (including itself), and the results of the three columns obtained. \ (A [. 3] \) , \ (A [. 5] \) case when the same reason. Therefore, in this column the total summation result 9. The number of squared column 1.

According to the law, continues to calculate the other columns, the resulting string of digits that is the sum of the binary representation.

Note that the sum of the binary number is converted to decimal time, since the return value may require long long storage, so you can not use math.h in the pow function (return type is double), to re-write one.

$ \ Color {green} {} $ View Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<math.h>
using namespace std;

long long a[1005], ans = 0;
long long pow(int base, int n)
{
    long long sum=1;
    while (n)
    {
        if (n&1) sum = base*sum;
        base *= base;
        n >>= 1;
    }
    return sum;
}

int main() {
    long long n, maxc = 0;
    cin >> n;
    for (int i = 1;i <= n;i++) {
        long long num, cnt = 0, nm;
        cin >> num;
        while (num) {//数num的二进制数中有几位是1
            if (num & 1) a[cnt]++;
            //num&1不为0,说明num的二进制数中的最右边那位是1
            //a[cnt]++表示计数第cnt列的1的个数
            cnt++;
            num >>= 1;
            //相当于num/=2
            //num二进制数右移1位
        }
        maxc = max(maxc, cnt);
        //更新最长的二进制数的长度 
    }
    for (int i = 0;i < maxc;i++)
        ans += a[i] * a[i] * pow(2, i);
    cout << ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/streamazure/p/12585153.html