或运算(思维)

或运算

时间限制: 1 Sec 内存限制: 128 MB 提交: 54  解决: 5 [提交][状态][讨论版]

题目描述

给定一个序列,我想知道该序列元素两两间相或后的和。

如:有四个元素a b c d

总和为a|b + a|c + a|d + b|c + b|d + c|d。

输入

第一行输入一个整数t,代表有t组测试数据(t <= 1000)

每组数据占2行,第一行有一个整数n代表序列元素个数,接下来一行有n个整数代表n个元素。

保证1 <= n <= 2500 且 0 <= 序列元素 <= 600。

输出

输出一个结果,保证不会超过int。

样例输入

4
4
1 2 3 4
5
1 2 3 4 5
3
7 8 5
6
4 5 1 6 7 8

样例输出

27
51
35
126
题解:存下每位有多少个1就好了,每次ans+前缀和;再加上少加了多少就好了;
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2510;
int a[MAXN];
int num[50];
int main(){
    int t, n;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        memset(num, 0, sizeof(num));
        int temp;
        int sum = 0, ans = 0;
        for(int i = 0; i < n; i++){
            scanf("%d", a + i);
            ans += sum;
            sum += a[i];
            temp = a[i];
            for(int j = 0; temp; j++){
                if(temp & 1){
                    ans += (i - num[j])*(1 << j);
                    num[j]++;
                }
                temp >>= 1;
            }
        }
        printf("%d
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/handsomecui/p/5516586.html