CF1148F

时间:2020-05-27
本文章向大家介绍CF1148F,主要包括CF1148F使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

思想僵化,2700的题都要看题解了。

不得不说这题真的挺妙。

废话不多说了,先假设所有val的和是正数。

考虑分组,把所有数按照最高位的1来分成62组,如果能使每一组最后的和都为负数,本题就被解决了。

具体来说,从低位到高位考虑每一组(mask最高位1的位置),如果这一组中数的val和大于0,就把答案的这一位设为1,再把所有mask中这一位是1的数val取反,否则把答案的这一位设为0。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long int

int n;
ll sum=0,ans=0;
int val[300000];
ll mask[300000];

int main(void)
{
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%lld",&val[i],&mask[i]);
        sum+=val[i];
    }
    if(sum<0)
        for(int i=0;i<n;i++)
            val[i]=-val[i];
    for(int i=0;i<62;i++){
        sum=0;
        for(int j=0;j<n;j++)
            if(mask[j]>=(1ll<<i)&&mask[j]<(1ll<<(i+1)))
                sum+=val[j];
        if(sum>0){
            ans+=(1ll<<i);
            for(int j=0;j<n;j++)
                if(mask[j]>>i&1)
                    val[j]=-val[j];
        }
    }
    printf("%lld\n",ans);
    return 0;
}
/*
*/
View Code

原文地址:https://www.cnblogs.com/2005lz/p/12976353.html