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)); }