您的位置:首页 > 其它

HDU 5106 Bits Problem(数位DP->二进制大数模拟)@

2017-04-20 17:07 525 查看
Bits Problem
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64u
Submit Status

Description

If the quantity of '1' in a number's binary digits is n, we call this number a n-onebit number. For instance, 8(1000) is a 1-onebit number, and 5(101) is a 2-onebit number. Now give you a number - n, please figure out the sum of n-onebit
number belong to [0, R).

Input

Multiple test cases(less than 65). For each test case, there will only 1 line contains a non-negative integer n and a positive integer 





































,
R is represented by binary digits, the data guarantee that there is no leading zeros.

Output

For each test case, print the answer module 1000000007 in one line.

Sample Input

1 1000


Sample Output

7


一开始想用三维数组来表示,但是情况很难考虑清楚就开了俩个二维数组一个表示数量,一个表示和,需要预处理,因为不包括右端点,中间的处理过程还需要一定的技巧。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
typedef long long LL;
const int mod = 1000000007;
const int N = 1005;
LL dp

, ct

, b
;
char str
;
int num
;

int main()
{
b[0]=1;
for(int i=1;i<N;i++)
b[i]=(b[i-1]*2)%mod;
ct[0][0]=1;
for(int i=1;i<N;i++)
{
ct[i][0]=1;
for(int j=1;j<=i;j++)
{
ct[i][j]=(ct[i-1][j-1]+ct[i-1][j])%mod;
}
}
memset(dp,0,sizeof(dp));
for(int i=1;i<N;i++)
{
for(int j=1;j<=i;j++)
{
dp[i][j]=(dp[i-1][j-1]+dp[i-1][j]+ct[i-1][j-1]*b[i-1]%mod)%mod;
}
}
int n;
while(scanf("%d %s",&n, str)!=EOF)
{
int len = strlen(str);
memset(num,0,sizeof(num));
for(int i=0;i<len;i++)
{
num[i+1]=(str[len-i-1]-'0');
}
LL ans=0, tmp=0;
int cnt=0;
for(int i=len;i>0;i--)
{
if(cnt>n)
break;
if(num[i])
{
ans+=((ct[i-1][n-cnt]*tmp%mod+dp[i-1][n-cnt])%mod);
ans%=mod;
tmp+=b[i-1];
tmp%=mod;
cnt++;
}
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: