Codeforces Global Round 8 D. AND, OR and square sum 题解(位运算)

题目链接

题目大意

给你长为n的a数组,你可以进行任意多次的操作,操作为选择a[i],a[j]使a[i]=a[i]|a[j],a[j]=a[i]&a[j].

在这里插入图片描述

题目思路

显然无论怎么操作把他们转换为二进制后,二进制每一位对应的1的个数不变。

直接把每个位的1算出来,然后分配,尽可能要大的数最大即可

代码

#include
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int n,bit[30],a[maxn];
ll ans;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        for(int j=0;j<=20;j++){
            bit[j]+=(a[i]&1);
            a[i]=a[i]>>1;
        }
    }
    for(int i=1;i<=n;i++){
        int x=0;
        for(int j=0;j<=20;j++){
            if(bit[j]){
                x=x+(1<<j);
                bit[j]--;
            }
        }
        ans+=1ll*x*x;
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(位运算)