BZOJ1677: [Usaco2005 Jan]Sumsets 求和

来源:互联网 发布:淘宝商品显示广告 编辑:程序博客网 时间:2024/05/09 18:58

Portal

【题意】

给出一个N(1≤N≤10^6),使用一些2的若干次幂的数相加来求之.问有多少种方法

手写列出来前几种情况找规律。
对于i为奇数,f[i]=f[i-1]
对于i为偶数,f[i]=f[i-1]+f[i>>1]

奇数时,一定会有一个1,也就是前一个数所分出的所有情况中,每一个里面加一个因子1
偶数时,分出的情况中若有1,可以看做是前一个数中所有的情况中加一个1
不含1的可以看做是,i>>1中所有的情况中,分解的因子*2。

【代码】

#include <iostream>#include <cstdio>#include <algorithm>#define N 1000005#define mod 1000000000using namespace std;typedef long long ll;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,m;int f[N];int main(){    n=read();f[1]=1;    for(int i=2;i<=n;i++)    {        f[i]=f[i-1];        if(!(i&1)) f[i]+=f[i>>1];        if(f[i]>=mod) f[i]-=mod;    }    printf("%d\n",f[n]);    return 0;}
0 0
原创粉丝点击