【Lightoj 1032 Fast Bit Calculations 】

来源:互联网 发布:阿里云服务器 yum 编辑:程序博客网 时间:2024/06/07 18:27

Fast Bit Calculations

Description
A bit is a binary digit, taking a logical value of either 1 or 0 (also referred to as “true” or “false” respectively). And every decimal number has a binary representation which is actually a series of bits. If a bit of a number is 1 and its next bit is also 1 then we can say that the number has a 1 adjacent bit. And you have to find out how many times this scenario occurs for all numbers up to N.

Examples:

  Number         Binary          Adjacent Bits     12                    1100                        1     15                    1111                        3     27                    11011                      2

Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains an integer N (0 ≤ N < 231).

Output
For each test case, print the case number and the summation of all adjacent bits from 0 to N.

Sample Input
7
0
6
15
20
21
22
2147483647
Sample Output
Case 1: 0
Case 2: 2
Case 3: 12
Case 4: 13
Case 5: 13
Case 6: 14
Case 7: 16106127360

一很好的朋友想到的,听他讲过之豁然开朗,想着打就出来了~~

#include<cstdio>#include<cstring>using namespace std;long long dp[36];int pa[36];long long QAQ(int x,int y) //快速幂{    int base = x ;    long long ans = 1;    while(y)    {        if(y&1)        ans *= x;        x *= x;        y >>= 1;    }    return ans;}int main(){    long long ans;    int i,k,j,pl;    memset(dp,0,sizeof(dp));    dp[0] = dp[1] = 0 ,dp[2] = 1;    for(i = 3 ; i <= 35 ; i++) // 先打个表    {        ans = dp[i - 1]; // 先加上上一位的总和        for(j = 0 ; j <= i - 2 ; j++)            ans += j * QAQ(2,i - j - 2) + dp[i - j - 2]; // 前 i 个 1 的贡献 + 当前位置的贡献        dp[i] = ans + i - 1;    }    int T,nl = 0 ,N,kl,x,y,ml;    scanf("%d",&T);    while(T--)    {        scanf("%d",&N);        memset(pa,0,sizeof(pa));        ans = 0;        kl = 0;        while(N)        {            if(N&1)              pa[++kl] = 1;            else              pa[++kl] = 0;            N >>= 1;        }        for(i = kl ; i >= 1 ; i--)        {            if(pa[i])            {                ans += dp[i - 1]; //先加上前一位                pl = 0;                ml = i;                while(pa[i])                {                    i--; pl++;                }                for(j = 0 ; j <= pl - 2 ; j++)                    ans += j * QAQ(2,ml - j - 2) + dp[ml - j -2];                    x = 1 ; y = 1;                for(k = 1 ; k <= i ; k++)                {                    y += (x * pa[k]);                    x <<= 1 ;                }                ans += (pl - 1) * y;            }        }        printf("Case %d: %lld\n",++nl,ans);    }    return 0;}
0 0