标签:组合数学
大致题意:
给定left,right,求出[left,right]中有多少数满足如下的性质:化成二进制形式后,0的个数大于等于1
组合数学,各种小边界处理很蛋疼
大致思路是
以10101100为例子,先求[0,10000000)中满足条件的数(想想该怎么求),然后求[100 00000,101 00000),[101 00 000,101 01 000)
[101 01 000,101 01 100)中的,全加起来
一开始思路错了
然后思路对了debug很久发现combination函数写错了。。。
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; long long Combination(long long n,long long r) { if(n==0) return 1; if(r>n-r) r=n-r; long long i,j,s=1; for(i=0,j=0;i<r;i++) { s*=(n-i); while(s%(r-j)==0&&(r-j)>=2) { s/=(r-j); j++; } } return s; } long long cal(long long a) { long long x=1;long long bit=1; long long ret=0; while(x<=a) { x<<=1; bit++; } bit--;x>>=1; // for(long long i=0;i<=bit/2;i++) // { // ret+=Combination(bit-1,i); // } for(long long i=bit-2;i>=0;i--) { for(long long j=0;j+1<=(i+1)/2 ;j++) { ret+=Combination(i,j); } } ret+=1; long long num1=1,num0=0; long long pos=bit; while(x>>=1,pos--) { if(x&a) num1++; else num0++; if(x&a) { for(long long i=pos-1;num0+1+i>=num1-1+pos-1-i && i>=0;i--) { ret+=Combination(pos-1,i); } } } return ret; } int main() { #ifndef ONLINE_JUDGE freopen("G:/1.txt","r",stdin); freopen("G:/2.txt","w",stdout); #endif long long A,B; scanf("%lld%lld",&A,&B); printf("%lld\n",cal(B+1)-cal(A)); return 0; }
POJ3252 RoundNumbers 【组合数学】,布布扣,bubuko.com
标签:组合数学
原文地址:http://blog.csdn.net/u011775691/article/details/29596757