数位统计Bestcoder18

来源:互联网 发布:2016上半年网络大电影 编辑:程序博客网 时间:2024/05/23 23:44

Online JudgeOnline ExerciseOnline TeachingOnline ContestsExercise AuthorF.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical Charts

Problem Archive
Realtime Judge Status
Authors Ranklist
 
     C/C++/Java Exams     
ACM Steps
Go to Job
Contest LiveCast
ICPC@China
Best Coder beta
VIP | STD Contests
Virtual Contests 
    DIY | Web-DIY beta
Recent Contests
Author ID Password  Register new ID
关于HDU-ACM集训队选拔以及HDU12月份校赛的安排 
【比赛提醒】BestCoder 你报名了吗?(点击报名) 
【科普】什么是BestCoder?如何参加?

Bits Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 186    Accepted Submission(s): 46


Problem 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(n1000,0<R<21000), 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
 

Source
BestCoder Round #18


  比如13,1101,假设要求含3个1的个数,就等于紫色区域3个1的个数加上绿色区域2个1的个数加上紫色区域1个1的个数,如果这条路径本身满足则还要加1。


  先初始化,用f[i][j]表示高度为i的完全二叉树的数中二进制恰好有j个1的数的个数,则有f[i][j]=f[i-1][j]+f[i-1][j-1]。
  然后从31位循环到第1位(如果此时路径上的1已经超过要求就退出循环),用k表示目前已经路径上已经有几个1。如果这一位是1,就k++,并且把这一位变成0。如果下一位是1,就需要加上以这一位为根的左子树上满足k-K(K是题目要求的1)个1的个数。

这个题求得是所有数的和,如果当前位是1则要把跟他平级的左子树的所有情况的值都加上。

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int maxn=1010;const int MOD=1000000007;LL C[maxn][maxn],W[maxn];int N;char s[maxn];void init(){    memset(C,0,sizeof(C));    C[0][0]=C[1][0]=C[1][1]=1;    for(int i=2;i<maxn;i++)    {        C[i][0]=C[i][i]=1;        for(int j=1;j<i;j++)            C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;    }    W[0]=1;    for(int i=1;i<maxn;i++)        W[i]=(W[i-1]*2)%MOD;}LL f(int len,int cnt){    LL ans=0;    if(len>=1&&cnt>=1)ans=(W[len]-1)*C[len-1][cnt-1];    ans=(ans%MOD+MOD)%MOD;    return ans;}int main(){    init();    while(scanf("%d%s",&N,s)!=EOF)    {        int len=strlen(s);        int cnt=0;        LL tmp=0,ans=0;        for(int i=0;i<len;i++)        {            if(N<cnt)break;            if(s[i]=='1')            {                ans=(ans+C[len-1-i][N-cnt]*tmp%MOD+f(len-1-i,N-cnt))%MOD;                cnt++;                tmp=(tmp+W[len-1-i])%MOD;            }        }        printf("%I64d\n",ans);    }    return 0;}



0 0
原创粉丝点击