Codeforces Global Round 8-D. AND, OR and square sum(位运算,贪心)

题目链接

题意:

给你一个数组,你可以从中任选两个数使得x=x&y,y=x|y,该操作可以执行无数次,求数组中每一位数的平方和的最大值。

思路:

如果我们多尝试几个例子你会发现,两个数经过上述位运算之后二进制的1的个数并不会改变,所以我们可以经过无数次的位运算操作之后将每一位的1转移到能转移到的最大的数的位置,最后得到的数组就是结果。

代码:

#include
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=2e5+7;
const int mod=998244353;
const int inf=0x7fffffff;
const double pi=3.1415926535;
using namespace std;
int flag[30],arr[N];
signed main()
{
    IOS;
    int n,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>arr[i];
        for(int j=0;j<=20;j++)
        {
            flag[j]+=(arr[i]&1);
            arr[i]=arr[i]>>1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        int x=0;
        for(int j=0;j<=20;j++)
        {
            if(flag[j])
            {
                x=x+(1<<j);
                flag[j]--;
            }
        }
        ans+=1ll*x*x;
    }
    cout<<ans<<endl;
    return 0;
}

你可能感兴趣的:(思维,贪心,位运算)