您的位置:首页 > 其它

acdream 1154 Lowbit Sum

2014-07-31 17:19 330 查看
先贴代码,以后再写题解。。。

首先,直接枚举肯定是会超时的,毕竟n就有10^9那么多。。。

对于每个数,我们先把它转化为二进制;例:21-->10101;

对于00001~10101,可以分为几个部分:

00001~10000;

10001~10100;

10101

因为对于每个数,从最右边的1截断,于是就可以理解为为:

00001~10000:;

001~100;

1;

设s[i]为二进制从右边数第 i+1 个数为1 (且其他数都为0)的lowbit sum;

则 s[i]=s[i-1]*2+2^i-2^(i-1);

则lowbit sum(21)=s[0]+s[2]+s[4];

设i=4;即 10000;

可分为 :

00001~01000 s[i-1];

01001~01111 s[i-1]-lowbit(01000)=s[i-1]-2^(i-1);  (从最右边的1截断,即可理解为 00001~00111 )

10000     lowbit(10000)=2^i;

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

ll s[100];

ll init (int n){
if (s
)
return s
;
s
=init (n-1)*2-(1<<(n-1))+(1<<n);//cout<<s
<<" ";
return s
;
}

int main (){
int n;    //while (cin>>n&&n) cout<<(1024>>n)<<endl;
ll ans=1;
int temp=2;
memset (s,0,sizeof s);
s[0]=1;
init (30);    //for (int i=0;i<=30;i++) cout<<s[i]<<" ";
while (~scanf ("%d",&n)){
ans=0;
for (int i=0;n&&i<30;i++) {
if (n&1)
ans+=s[i];//cout<<ans<<endl;
n>>=1;
//n/=2;
}
printf ("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: