[CSP-S2020]动物园 题解

题意分析

给出一些二进制串,并给出一些位数,问还能再加上多少个二进制串,使得这些二进制串按位或运算的结果在给定的位数上不变。

思路分析

显然只有那些有被给出并且在之前给出的二进制串中没有出现的位数不能出现。每有一个位数不能出现,就要减掉一半的二进制串。最后减去刚开始给出的那些就可以了。

根据数据范围,显然要开 ull 。注意特判 $k=64$ 的情况。此时若 $n=0$ ,答案为 $2^{64}$ ,只能用字符串输出,即 18446744073709551616 ;否则可以用 $2^{64}-1-n+1$ 的方法防止溢出。

//FJ-00445
//NOIP2020 RP++
#include<iostream>
#include<cstdio>
#define ull unsigned long long
using namespace std;
const int N=1e6+100,M=70;
int n,m,c,k,cnt;
bool pd[M];
ull f,ans;
int main()
{
    scanf("%d%d%d%d",&n,&m,&c,&k);ans=k;
    for(int i=1;i<=n;i++)
    {
        ull x;scanf("%llu",&x);
        f|=x;
    }
    for(int i=1,x,y;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        pd[x]=1;
    }
    for(int i=0;i<k;i++)
        if(pd[i] && !(((ull)1<<i)&f))//有给出但是在之前给出的二进制串中没有出现
            cnt++;
    if(!cnt && k==64)
        if(!n)
            puts("18446744073709551616");//k=64,n=0
        else
            cout<<(ull)18446744073709551615-n+1;//k=64,n>0
    else
        cout<<((ull)1<<(ans-cnt))-n;//一般情况
    return 0;
}

 

原文地址:https://www.cnblogs.com/TEoS/p/13956294.html