BZOJ2728: [HNOI2012]与非
容易推出能用nand和括号做出所有逻辑运算。那么可以尝试乱搞,利用线性基做任意次异或,再加上几次别的运算,就很有可能能得到所有本来能得到的数了。
#include<cstdio>
int n,m;
typedef long long ll;
ll l[60],j,s,t;
void up(ll&i,ll j){
j^=i,i<j?0:i=j;
}
void ins(ll j){
for(int i=m-1;~i;--i){
up(j,l[i]);
if(j>>i&1){
for(int k=i-1;~k;--k)
up(j,l[k]);
for(int k=m-1;k>i;--k)
up(l[k],j);
l[i]=j;
break;
}
}
}
ll val(ll j){
ll s=0,t=0;
for(int i=m-1;~i;--i)
if(l[i]){
s=s<<1|(t^l[i])<j;
if(s&1)
t^=l[i];
}
return s+!!j;
}
int main(){
scanf("%d%d%lld%lld",&n,&m,&s,&t);
while(n--){
scanf("%lld",&j);
for(int i=m-1;~i;--i)
ins(j|l[i]);
}
printf("%lld\n",val(t+1)-val(s));
}

浙公网安备 33010602011771号