码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ.3209.花神的数论题(数位DP)

时间:2018-04-01 20:49:45      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:long   href   math   fine   desc   problem   class   www   数位   

题目链接

\(Description\)

\(sum_i\)表示\(i\)的二进制表示中\(1\)的个数,求\[\prod_{i=1}^nsum_i\ mod\ 10000007\].

\(Solution\)

因为\(n\)的二进制有\(logn\)位,所以我们考虑枚举x,求满足\(sum_i=x\)\(i\)的个数,然后就可以快速幂解决了。
求个数用数位DP。

//852kb 84ms
#include <cstdio>
#include <cstring>
#define mod (10000007)
typedef long long LL;
const int N=60;

LL n,A[N],f[N][N];
bool vis[N][N];

LL FP(LL x,LL k)
{
    LL t=1;
    for(; k; k>>=1,x=x*x%mod)
        if(k&1) t=t*x%mod;
    return t;
}
LL DFS(int pos,int cnt,bool lim)
{
    if(cnt<0||pos<cnt) return 0;
    if(!pos) return !cnt;
    if(!lim && vis[pos][cnt]) return f[pos][cnt];
    int up=lim?A[pos]:1; LL res=0;
    for(int i=0; i<=up; ++i)
        res+=DFS(pos-1,cnt-i,i==up&&lim);
    if(!lim) vis[pos][cnt]=1,f[pos][cnt]=res;
    return res;
}

int main()
{
    scanf("%lld",&n);
    for(A[0]=0; n; n>>=1) A[++A[0]]=n&1;
    LL res=1ll;
    for(int i=1; i<=A[0]; ++i)
        (res*=FP(i,DFS(A[0],i,1)))%=mod;
    printf("%lld",res);

    return 0;
}

BZOJ.3209.花神的数论题(数位DP)

标签:long   href   math   fine   desc   problem   class   www   数位   

原文地址:https://www.cnblogs.com/SovietPower/p/8687983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!