• 【洛谷】4317:花神的数论题【数位DP】


    P4317 花神的数论题

    题目背景

    众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。

    题目描述

    话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。 花神的题目是这样的:设 sum(i)表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你 i=1Nsum(i) ,也就是sum(1)sum(N)的乘积。

    输入输出格式

    输入格式:

     

    一个正整数 N。

     

    输出格式:

     

    一个数,答案模 10000007 的值。

    输入输出样例

    输入样例#1: 复制
    3
    输出样例#1: 复制
    2

    说明

    对于 100% 的数据,N≤10^15


    Solution

    数位DP

    但是不是直接处理出乘积,而是枚举$i$,处理出有多少个数恰好有$i$个1.

    最后直接用快速幂乘起来即可。

    Code

     

    #include<bits/stdc++.h>
    #define LL long long
    #define mod 10000007
    using namespace std;
    
    LL n;
    
    LL mpow(LL a, LL b) {
        LL res = 1;
        for(; b; b >>= 1, a = a * a % mod)
            if(b & 1)    res = res * a % mod;
        return res;
    }
    
    LL dp[55][2][55][55];
    int num[55];
    LL dfs(int dep, int up, int sum, int d) {
        if(!dep && sum == d)    return dp[dep][up][sum][d] = 1;
        if(!dep)    return dp[dep][up][sum][d] = 0;
        if(~dp[dep][up][sum][d])    return dp[dep][up][sum][d];
        int tot = up ? num[dep] : 1;
        LL tmp = 0;
        for(int i = 0; i <= tot; i ++)
            tmp += dfs(dep - 1, up && i == tot, sum + i, d);
        return dp[dep][up][sum][d] = tmp;
    }
    
    LL ans[55];
    LL cot(LL x) {
        int t = 0;
        memset(num, 0, sizeof(num));
        while(x) {
            num[++t] = x % 2;
            x >>= 1;
        }
        for(int i = 1; i <= 50; i ++) {
            memset(dp, -1, sizeof(dp));
            ans[i] = dfs(t, 1, 0, i);
        }
        LL res = 1;
        for(int i = 1; i <= 50; i ++)
            res = (res * mpow(i, ans[i])) % mod;
        return res;
    }
    
    int main() {
        scanf("%lld", &n);
        printf("%lld", cot(n));
        return 0;
    }

     

     

  • 相关阅读:
    如何用js判断一个对象是不是Array
    js实现数组去重怎么实现?
    点击一个ul的五个li元素,分别弹出他们的序号,怎么做?
    盒子模型
    13. 查看网络端口、配置网络
    12. 查看系统硬件配置
    11. 系统状态管理
    9. iptables 配置
    10. 编译软件包
    8. 管理软件包
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9836742.html
Copyright © 2020-2023  润新知