首页 > 代码库 > Bzoj2728 [HNOI2012]与非
Bzoj2728 [HNOI2012]与非
Submit: 753 Solved: 361
Description
Input
输入文件第一行是用空格隔开的四个正整数N,K,L和R,接下来的一行是N个非负整数A1,A2……AN,其含义如上所述。 100%的数据满足K≤60且N≤1000,0<=Ai<=2^k-1,0<=L<=R<=10^18
Output
仅包含一个整数,表示[L,R]内可以被计算出的数的个数
Sample Input
3 3 1 4
3 4 5
3 4 5
Sample Output
4
HINT
样例1中,(3 NAND 4) NADN (3 NAND 5) = 1,5 NAND 5 = 2,3和4直接可得。
Source
day1
位运算 线性基 DP
一个数与非自己,结果等于非(Not)
Not(x Nand y) = x And y
not+and可以搞出所有逻辑运算。
可以据此从读入的数中找出所有线性基,然后由大到小使用线性基,进行数位DP。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define LL long long 6 using namespace std; 7 const int mxn=1010; 8 LL read(){ 9 LL x=0,f=1;char ch=getchar();10 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}11 while(ch>=‘0‘ && ch<=‘9‘){x=x*10-‘0‘+ch;ch=getchar();}12 return x*f;13 }14 int n,k;15 LL L,R;16 LL a[mxn],b[mxn],p[mxn];17 int cnt=0;18 bool vis[mxn];19 LL solve(LL x){//数位DP 20 if(x==-1)return -1;21 int i;22 LL res=0,ans=0;23 for(i=1;i<=cnt;i++)24 if(res+p[i]<=x){25 res+=p[i];26 ans+=(1LL<<cnt-i);27 }28 return ans;29 }30 int main(){31 int i,j;32 n=read();k=read();L=read();R=read();33 LL ed=(1LL<<k)-1;34 for(i=1;i<=n;i++)a[i]=read();35 LL now=0;36 for(i=k-1;i>=0;i--){37 if(!vis[i]){38 now=ed;39 for(j=1;j<=n;j++){40 if((a[j]>>i)&1) now&=a[j];41 else now&=(~a[j]);42 }43 for(j=0;j<=i;j++)44 if((now>>j)&1)vis[j]=1;45 p[++cnt]=now;46 }47 }48 printf("%lld\n",solve(R)-solve(L-1));49 return 0;50 }51
Bzoj2728 [HNOI2012]与非
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。