csp-s2020动物园

先看数据规模

20%的数据点pi互不相同,那么答案就是2^(k-m)-n。这个20分是非常容易拿的。

当然,本题是要拿满分的。拿满分,关键是看两个点

一是位运算(怎么想到的?看数据规模,肯定要注意时间复杂度了),将动物编号 | 后得到一个二进制数an,接下来将an与食物清单&,如果得到的非零,那么这个食物可选可不选,如果是零,那么这个食物就不能选。将这些不能选的位置数量记下来,记作cns。那么答案就是2^(k-cns)-n。

二是数据范围,因为k最大可取64,而2^64超出了ull的上限,可以特判,当k-cns==64,且n=0的时候,直接输出2^64。可以用window计算器科学计数器模式计算得到。

本题致命点在1<<p,没有说明,则它的最高位是符号位,因此要改成1ull <<p

#include<bits/stdc++.h>
#define maxn 100000005
#define ll long long 
#define ull unsigned long long 
using namespace std;

unsigned long long n,m,c,k;
unsigned long long a,an=0,p,q,cns;
bool vis[maxn];

int main()
{
	freopen("zoo14.in","r",stdin);
	cin>>n>>m>>c>>k;
	for(int i=1;i<=n;i++)
	{
		cin>>a;
		an|=a;
	}
	//cout<<an<<endl;
	for(int i=1;i<=m;i++)
	{
		cin>>p>>q;
		if(an & (1ull<<p)) continue;//第p个食物需要购买,不影响答案——————这里要写成1ull<<p,不能写1<<p,否则对于第14个测试点cns=10 
		vis[p]=1;//第p个食物不用购买,将影响答案 
	}
	for(int i=0;i<k;i++) //统计有多少种食物限制没有用到,这些限制不要启用 
		if(vis[i])cns++;
	if(k-cns==64)
	{
		if(n==0)
			printf("18446744073709551616\n");  //用电脑自带的计算器科学计数器模式计算得到2^64 
		else
			cout<<(unsigned long long)(-n) << endl;
		return 0;
	}
	cout<<(unsigned long long)pow(2,k-cns)-n;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值