[题解]luogu_P4317_花神的数论题(数位dp

本文深入探讨了二进制环境下数位动态规划(DP)算法的应用,通过统计1出现次数的优化策略,转化为熟悉的问题解决方案。文章详细介绍了状态设计、递归函数实现及快速幂技巧,为读者提供了理解和应用复杂算法的实用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然是二进制但是和普通的数位dp没什么差别,统计1出现次数的乘积不如统计每个出现次数的数量,然后对应快速幂一下,转化成了平时熟悉的方案数,

状态设计:dfs里传什么参就开哪些状态,可以包括是否达到上限(lmt)之类的

#pragma GCC optimize(19260817)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=10000007;
ll n;
ll f[51][51][51][2],num[51];
ll qpow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)(ans*=a)%=mod;
        (a*=a)%=mod;
        b>>=1;
    }
    return ans%mod;
}
ll dfs(int x,int y,int lmt,int now){//x位y个1正统计now 
    if(x==0)return y==now;
    if(f[x][y][now][lmt]!=-1)return f[x][y][now][lmt];
    int top=lmt?num[x]:1;
    ll ans=0;
    for(int i=0;i<=top;i++)
    ans+=dfs(x-1,y+(i==1),lmt&&i==top,now);
    f[x][y][now][lmt]=ans;
    return ans;
}
ll g[51];
ll solve(){
    int len=0;
    while(n){
        num[++len]=n&1;
        n>>=1;
    }
    for(int i=1;i<=50;i++){
        memset(f,-1,sizeof(f));
        g[i]=dfs(len,0,1,i);
    }
    ll ans=1;
    for(int i=1;i<=50;i++)
    (ans*=qpow(i,g[i]))%=mod;
    return ans;
}
int main(){
    scanf("%lld",&n);
    printf("%lld\n",solve());
}

 

转载于:https://www.cnblogs.com/superminivan/p/11574071.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值