T1:儒略日
T2:動物園
根據題意,顯然有:當飼料清單上某一位為0時,不能再加入一種動物使得這一位變為1,其余的位置可以為0或1
令\(S\)為所有飼料清單上第\(P_i\)為\(0\)的個數(注意要去重)
那么最終答案就是\(2^{k-S}-n\)(\(k,n\)即為題目中所給的\(k,n\))
初始的飼料清單可以記錄一個數\(F=0\),則\(F\) \(xor_{i=1}^na_i\)的結果就是飼料清單的值(令結果為\(F\))
判斷第\(P_i\)位是否為\(0\),可以判斷\(F|(1ull<<p_i)\)是否等於\(F\)。(這里的\(1\)要用\(ull\))
需要特別注意的是最\(k\)最大可以達到\(64\),所以答案一定要用\(unsigned\) \(long\) \(long\)保存,不然會爆!
然而太弱的我並沒想到\(k=64,S=0,n=0\)這種情況,因為它的答案為\(2^{64}\),\(ull\)並不能存下它,那么就只有特判了!
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
unsigned ll read()
{
unsigned ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
bool vis[1000];
unsigned ll n,m,c,k,F,q,p;
int main()
{
freopen("zoo.in","r",stdin);
freopen("zoo.out","w",stdout);
n=read(),m=read(),c=read(),k=read(),F=0;
for(unsigned ll i=1,a;i<=n;i++)a=read(),F=F|a;
for(unsigned ll i=1;i<=m;i++)
{
p=read(),q=read();
if((F|(1ull<<p))!=F&&!vis[p])k--,vis[p]=true;
}
if(k==64&&n==0)printf("18446744073709551616\n"),exit(0);
unsigned ll ans=(unsigned ll)pow(2,k)-n;
printf("%llu\n",ans);
return 0;
}