UVa11645

来源:互联网 发布:我的世界java内存不足 编辑:程序博客网 时间:2024/05/22 17:35

题目链接

简介:
A(n)表示n的二进制中有多少个“11”出现
计算A(0)+A(1)+…+A(n)

分析:
一眼看出递推式:

A(n)=A(n/2)+(n/2和n都是奇数 ? 1:0)

这个式子算A(n)是很简单啦,但是求前缀和我就GG了

这道题实际和 UVA 11038 这题类似,枚举中间,然后处理两边的情况。
不过本题最大的答案会超过ll,要用高精度,不过借鉴大佬的方法,直接用两个数字来保存一个数字,这样能保存到2个ll的长度,就足够存放答案了

tip

说实话我不大懂这道题

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const ll M=1e13;ll n,p,q;void add(ll x){    q+=x;    p+=q/M;    q%=M;}void solve(){    p=q=0;    ll a=n,b=1;    while (n>1)    {        add((n>>2)*b);        if ((n&3)==3)           add((a&(b-1))+1);        b<<=1;        n>>=1;    }    if (p)    {        printf("%lld",p);        printf("%013lld\n",q);    }    else        printf("%lld\n",q);}int main(){    int cas=0;    while (scanf("%lld",&n)!=EOF&&n>=0)    {        printf("Case %d: ",++cas);        solve();    }    return 0;}
原创粉丝点击