fzoj 1559 Count Zeros(数学:推理)

来源:互联网 发布:linux修改启动画面 编辑:程序博客网 时间:2024/06/05 15:38

给定一个n,求1-n对应的二进制数中0出现的总次数

我是枚举了几个数之后推导出来的,并没有严谨性证明

因为没有看到输出要求的mod2007,还去贴了个大数模板...

后来看ppt上才知道要mod2007,然后再交自己的代码就A了

枚举n=0, 1, 2, 3, 4, 5后发现:

f(0) = 0f(1) = 1 f(2) = 3f(3) = 8f(4) = 21f(5) = 54令f(n) = 2*f(n-1)+g(n)g(2) = g(1)+2-1 = 2g(3) = g(2)+2^2-1 = 5g(4) = g(3)+2^3-1 = 12可以发现g(n)-g(n-1) = 2^(n-1)-1


严谨证明如下:

F[i]   =SumZero{1..2i}F[i-1]=SumZero{1..2i-1}(2i-1+1)..2i与1..2i-1都为2i-1个数字F[i]=F[i-1]+(i-1)*2i-2+12i-1个数,每个数填满i-1位置,共填(i-1)*2i-1,在这其中0、1出现的概率是相同的所以一共是(i-1)*2i-1/2,即(i-1)*2i-2例如:从1001..(1111)10000最后3位经历了000->111的过程而10000还有右数第4的1没有被计算过所以结果还要加1。

代码如下:

#include <cmath>#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std; int main(void) {    int n, tmp, ans;    while(scanf("%d", &n) != EOF) {        ans = tmp = 1;        for(int i=2; i<=n; ++i) {            ans = (ans+ans+tmp)%2007;            tmp = (tmp+tmp+(i-2))%2007;        }        if(n == 0) ans = 0;        if(n == 1) ans = 1;        cout << ans << endl;    }    return 0;}


0 0
原创粉丝点击