题解 P7076 【动物园(洛谷民间数据)】
考场思路
看到题目的限制条件,我们容易想到先把每一种动物的编号的二进制都表示出来,把每种动物的编号全部或起来,然后枚举每条限制,如果或的结果第
再分析数据规模,发现
于是我们直接开一个
如果第
反之,则所有
那么,在可以新加入动物的编号的二进制中,没有被标记的二进制位都可以取0或1两个值。
然后把遍历所有二进制位求有多少种动物可以在动物园里,算出2的次幂,减去已有的n种动物,即为答案。
最后,由于
另外,在
考场上我好像又没特判,又把读入ull写错了,沦为70pts。。。
具体参见代码。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1e6+6;
int n,m,k,c,ans;
unsigned long long a[maxn],sum,ani,mi;
struct rues{int p,q;}fg[maxn];
bool vis[100000007];
int main(){
freopen("zoo.in","r",stdin);
freopen("zoo.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&c,&k);
for(int i=1;i<=n;i++){
scanf("%llu",&a[i]);
sum|=a[i];
}
for(int i=1;i<=m;i++)
scanf("%d%d",&fg[i].p,&fg[i].q);
for(int i=1;i<=m;i++)
if(sum&(1ull<<fg[i].p))
vis[fg[i].q]=1;
for(int i=1;i<=m;i++)
if(vis[fg[i].q]==0)
ani|=(1ull<<fg[i].p);
for(int i=0;i<k;i++)
if((ani&(1ull<<i))==0)ans++; //2的几次幂
if(ans==64)cout<<18446744073<<709551616-n; //特判很重要
else{
mi=1;
for(int i=1;i<=ans;i++)mi*=2;
printf("%llu",mi-1ull*n);
}
return 0;
}
多说几句
考完后发现题目中有这么句话:
数据保证所有
a_i 互不相同,所有的q_i 互不相同。
那么可能有更加简便的方法,欢迎指正。