牛客练习赛60 A大吉大利(异或思维)

    地址:https://ac.nowcoder.com/acm/contest/4853#question

     题意:中文不多解释啦。

     解析:根据题意,有暴力:

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

        但是1e5*1e5,1s过不去的。比赛时想了几个优化方法,但是无奈都过不了。赛后看了后才恍然大悟,只怪自己动手能力太差,惭愧惭愧!

       首先&的运算,同为1,才为1,否则为0。对于结果,二进制只有1,1能贡献。看样例,全化成二进制是这样的:

    对于a列来讲:模拟一下过程,可以得出9个1来,而本身是有3个1。对于b列,本身有2个1,可以&出4个1来。可以推测,每一位可&出1的数目是本身1数目的平方。上述样例可以得出:4  4  9,那么总结果就是4*2^2+4*2^1+9*2^0。所以开个数组来记录二进制每一位产生1的数目,最后加一下就好了。a[]记得开LL。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int main()
{
    ll a[74];
    int n;
    cin>>n;
    memset(a,0,sizeof(a));
    int tot=0;
    for(int i=1;i<=n;i++)
    {
        ll x;
        cin>>x;
        tot=0;
        while(x)
        {
            if(x%2==1)
                a[tot]++;
            x=x/2;
            tot++;
        }
    }
    ll sum=0;
    for(ll i=0;i<66;i++)
        {
            sum+=a[i]*a[i]<<i;  //<<i表示2^i次方
        }
    cout<<sum<<endl;
}

    貌似是不需要快速幂的,ac了。

原文地址:https://www.cnblogs.com/liyexin/p/12590074.html