题目问区间有多少个数字的二进制0的个数大于等于1的个数。

用数学方法求出0到n区间的合法个数,然后用类似数位DP的统计思想。

我大概是这么求的,确定前缀的0和1,然后后面就是若干个0和若干个1的不重复全排列数。。

写得挺痛苦的。。另外A[i][j]表示i个0和j个1的不重复全排列数,即A[i][j]=(i+j)!/i!/j!,这个可以从A[i-1][j]或A[i][j-1]求出来,这样就不用担心乘法溢出了。

 #include<cstdio>
#include<cstring>
using namespace std;
long long d[][];
long long cnt(int zero,int one,int len){
long long res=;
for(int i=; i<=len; ++i){
int j=len-i;
if(i+zero<j+one) continue;
res+=d[i][j];
}
return res;
}
long long calu(int a){
int len=;
while(len!=- && ((a>>len)&)==) --len;
if(len==-) return ;
long long res=;
for(int i=; i<len; ++i){
res+=cnt(,,i);
}
int zero=,one=;
for(int i=len-; i>=; --i){
if((a>>i)&){
res+=cnt(zero+,one,i);
++one;
}else{
++zero;
}
}
zero=; one=;
for(int i=; i<=len; ++i){
if((a>>i)&) ++one;
else ++zero;
}
return res+(zero>=one);
}
int main(){
d[][]=;
for(int i=; i<; ++i){
for(int j=; j<; ++j){
d[i+][j]=d[i][j]*(i+j+)/(i+);
d[i][j+]=d[i][j]*(i+j+)/(j+);
}
}
int a,b;
while(~scanf("%d%d",&a,&b)){
printf("%lld\n",calu(b)-calu(a-));
}
return ;
}

最新文章

  1. strom的使用01
  2. android基础(六)android的消息处理机制
  3. bootstrap-table 分页的问题
  4. CSS Sprite雪碧图应用
  5. 入门:HTML表单与Java 后台交互(复选框提交)
  6. Block深入浅出
  7. .net 邮件批量发送功能源码
  8. asp.net BulletedList绑定数据及vs2013添加数据库文件
  9. Makefile常用信息查询页
  10. Arduino 各种模块篇 RGB LED灯
  11. DEDECMS整站复制
  12. JavaScript作用域链和垃圾回收机制
  13. 【javaFX学习】(二) 面板手册--1
  14. Javascript中没有块级作用域(模仿)
  15. CSS(四)
  16. 19.3.25 sql查询语句
  17. nodejs+express+socket.io
  18. MRO
  19. 【BZOJ3165】[HEOI2013]Segment(李超线段树)
  20. 查看mysql库中所有表的信息--INFORMATION_SCHEMA

热门文章

  1. shell编程报错 [: missing `]&#39;
  2. 微信开发学习日记(八):7步看懂weiphp插件机制,核心目标是响应微信请求
  3. HTML前端
  4. Redis和Memcache的区别分析
  5. 【Python】Django 聚合 Count与Sum用法,注意点
  6. TCP/IP详解学习笔记(5)-- ICMP:internet 控制报文协议
  7. 对于sharepoint 的解决方案的实际说明
  8. swift 中String,Int 等类型使用注意,整理中
  9. Java for LeetCode 141 Linked List Cycle
  10. [Android Pro] PackageManager#getPackageSizeInfo (hide)