admin 管理员组

文章数量: 887007

牛客练习赛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;
} 

本文标签: 牛客练习赛60 A 大吉大利 题解(位运算)