牛客练习赛60 A 大吉大利 题解(位运算)

题目链接

题目大意

在这里插入图片描述

题目思路

首先上一个暴力代码(会t)了解一下题目

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

首先明白了题目的意思,暴力肯定t,其实有关位运算的题目要一般都要考虑贡献问题,往那方面思考,很快就会有答案。
我们直接考虑答案的每一位1的个数,把每一个 ai的每一位都统计一下,对答案的某一位,如果有 k 个1,那实际上就是 k^2个1,模拟一下二进制加法即可.

代码

#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,a[maxn],cnt[40]; 
ll ans,sum;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<=30;j++){
			if(a[i]&1<<j){
				cnt[j]++;
			}
		}
	}	
	for(int i=0;i<=30;i++){
		ans+=1ll*(1<<i)*cnt[i]*cnt[i];
	}
	printf("%lld",ans);
	return 0;
} 
发布了68 篇原创文章 · 获赞 2 · 访问量 2242

猜你喜欢

转载自blog.csdn.net/m0_46209312/article/details/105267243