洛谷 P4317 花神的数论题

题目传送门

数位dp

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

long long n,f[70][2][70];
long long s[70],len,mod = 10000007;

inline long long max(int a,long long b) {
    if(a > b) return a;
    return b;
}

inline long long dfs(int d,bool li,long long sum) {
    if(d == 0) return max(1,sum) % mod;
    if(f[d][li][sum] != -1) return f[d][li][sum] % mod;
    int res = li ? s[d] : 1;
    long long num = 1;
    for(int i = 0;i <= res; i++)
        (num *= dfs(d - 1,li && i == res,sum + ((i == 1) ? 1 : 0))) %= mod;
    f[d][li][sum] = num % mod;
    return num % mod;
}

inline long long solve(long long x) {
    len = 0;
    while(x) {
        s[++len] = x % 2;
        x /= 2;
    }
    memset(f,-1,sizeof(f));
    return dfs(len,1,0);
}

int main() {
    scanf("%lld",&n);;
    printf("%lld",solve(n));
    return 0;
}

 

posted @ 2020-09-02 23:07  Mr^Simon  阅读(132)  评论(0编辑  收藏  举报