博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51nod 1301 集合异或和——异或dp
阅读量:5038 次
发布时间:2019-06-12

本文共 1573 字,大约阅读时间需要 5 分钟。

题目:

好题!看了TJ才会。

因为是不可重集合,所以当然有前 i 个表示A和B都考虑的前 i 个,新加一个讨论放A、放B、不放。

A<B在异或上看就是有一位,它前面的A和B都一样,该位A是0、B是1。该位可以枚举。然后就能dp了。

注意边界细节……和标程对拍真愉快……

#include
#include
#include
#include
using namespace std;const int N=2005,M=4100,mod=1e9+7;int n,m,mi,mj,lm,dp[2][M][2],ans,bin[25];int calc(int a){ int ret=0; while(a) a>>=1,ret++; return ret;}void ad(int &x,int y){ x=(x+y>=mod?x+y-mod:x+y);}int main(){ scanf("%d%d",&n,&m); mi=max(n,m); lm=calc(m); int tmp=calc(mi); bin[1]=1; for(int i=2;i<=tmp;i++) bin[i]=(bin[i-1]<<1);//tmp not lm!!! bin[tmp+1]=(bin[tmp]<<1); mj=bin[tmp+1]-1; for(int t=1;t<=lm;t++) { memset(dp[0],0,sizeof dp[0]);///not dp[0] if mj isn't gu ding dp[0][0][0]=1;// mj=1; for(int i=1,u,v;i<=mi;i++) { u=(i&1);v=!u;// if(i>=bin[mj])mj++;// for(int j=0;j<=bin[mj];j++) for(int j=0;j<=mj;j++) { dp[u][j][0]=dp[v][j][0]; dp[u][j][1]=dp[v][j][1]; if(i<=n)//A { ad(dp[u][j][0],dp[v][j^i][0]); ad(dp[u][j][1],dp[v][j^i][1]); } if(i<=m)//B { bool d=(i&bin[t]); ad(dp[u][j][0],dp[v][j^i][0^d]); ad(dp[u][j][1],dp[v][j^i][1^d]); } } } int d=(mi&1);// mi not n!!! for(int i=bin[t];i

 

转载于:https://www.cnblogs.com/Narh/p/9607097.html

你可能感兴趣的文章
redhat 7 源码安装 mysql5.5.49
查看>>
Android官方技术文档翻译——ApplicationId 与 PackageName
查看>>
Feign使用Hystrix无效原因及解决方法
查看>>
Sam做题记录
查看>>
hexo 搭建博客
查看>>
建造者模式(屌丝专用)
查看>>
Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
查看>>
C++的引用
查看>>
python itertools
查看>>
http://lorempixel.com/ 可以快速产生假图
查看>>
编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成...
查看>>
文件操作
查看>>
NYOJ-613//HDU-1176-免费馅饼,数字三角形的兄弟~~
查看>>
graphite custom functions
查看>>
ssh无密码登陆屌丝指南
查看>>
一个自己写的判断2个相同对象的属性值差异的工具类
查看>>
[CF803C] Maximal GCD(gcd,贪心,构造)
查看>>
oracle连接的三个配置文件(转)
查看>>
Java 8 中如何优雅的处理集合
查看>>
[HNOI2012]永无乡 线段树合并
查看>>