poj 3252 Round Numbers

http://poj.org/problem?id=3252

题意:求一个区间内的数化为二进制后0的个数大于1的个数的数的个数。 用组合数求出小于一个数的长度的所有情况,然后再单独处理这个长度这种情况。然后右端点求的个数减去左端点求的个数就是答案。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <algorithm>

 4 #define ll __int64

 5 using namespace std;

 6 

 7 ll s,t;

 8 int a[100];

 9 ll c[110][110];

10 void inti()

11 {

12     for(int i=0; i<=32; i++)

13     {

14         c[i][0]=1;

15         for(int j=1; j<=i; j++)

16         {

17             c[i][j]=(c[i-1][j-1]+c[i-1][j]);

18         }

19     }

20 }

21 

22 ll Get_NUM(int n)

23 {

24     if(n<=1) return 0;

25     memset(a,0,sizeof(a));

26     int cnt=0;

27     while(n)

28     {

29         a[cnt++]=n%2;

30         n>>=1;

31     }

32     ll ans=0;

33     for(int i=2; i<cnt; i++)

34     {

35         for(int j=(i+1)>>1; j<i; j++)

36         {

37             ans+=c[i-1][j];

38         }

39     }

40     int t1=1,t2=0;

41     for(int i=cnt-1; i>=0; i--)

42     {

43         if(a[i-1])

44         {

45           for(int j=i-1; ;  j--)

46           {

47               int num1=i-1-j+t1;

48               int num2=j+t2+1;

49               if(num1>num2) break;

50               ans+=c[i-1][j];

51           }

52           t1++;

53         }

54         else

55         {

56             t2++;

57         }

58     }

59     if(t1<=t2)

60     {

61         ans++;

62     }

63     return ans;

64 }

65 int main()

66 {

67     inti();

68     while(scanf("%I64d%I64d",&s,&t)!=EOF)

69     {

70          printf("%I64d\n",Get_NUM(t)-Get_NUM(s-1));

71     }

72     return 0;

73 }
View Code

 

你可能感兴趣的:(number)