「CSPS 2020」动物园

description

luogu
loj(暂无数据)

solution

这道题作为T2,对选手们考试开始后先通看一遍所有题目的好习惯,以及判断究竟谁才是真正的签到题的重要能力进行了较好的锻炼,
特别准备的\(n=0,k=64\)更是让每个同学从此对\(long \ long\)\(unsigned \ long \ long\)的范围究竟是多少印象深刻。
实在是出题人良心的馈赠,将为每位选手的oi之路上平添一份助力。

事实上,这道题属实是一道签到题,并且题目还保证了\(q_i\)互不相同
于是直接对于第\(k\)位为1的要求,如果已有的动物中没有满足这种要求的,那么所有第\(k\)位为1的动物都不能养
所以记录一下多少个二进制位可以自由选择\(0/1\),假设是\(cnt\),那么答案就是\(2^{cnt}-n\)
注意特判\(n=0,k=64\)的情况,此时答案\(2^{64}\)会超出\(unsigned \ long \ long\)的范围

code

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=2e6+10;
int n,m,c,k,p[N],q[N];
ll a[N];
inline ll readll(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
inline int readint(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
int f[100],w[100];
signed main(){
	freopen("zoo.in","r",stdin);
	freopen("zoo.out","w",stdout);
	n=readint();m=readint();c=readint();k=readint();
	for(int i=1;i<=n;++i) a[i]=readll();
	for(int i=0;i<k;++i){
		for(int j=1;j<=n;++j){
			if(a[j]&(1ull<<i)){
				f[i]=1;
				break;
			}
		}
	}
	ll cnt=k;
	for(int i=1;i<=m;++i){
		p[i]=readint();q[i]=readint();
		if(p[i]>=k) continue;
		if(!f[p[i]]){
			if(!w[p[i]]) cnt--;
			w[p[i]]=1;
		}
	}
	if(n==0&&cnt==64){
		puts("18446744073709551616");
		return 0;
	} 
	if(cnt==64){
		printf("18%llu\n",446744073709551616ull-(1ull*n));
		return 0;
	}
	cout<<(1ull<<cnt)-n;
	return 0;
}
原文地址:https://www.cnblogs.com/tqxboomzero/p/13950656.html