zoukankan      html  css  js  c++  java
  • BZOJ3209: 花神的数论题

    重在建模QwQ,要将题意转化为

    枚举1的个数k,计算有多少个数含有k个1,(因为数位dp就是来做,有多少满足的数,且不关注数的大小)

    最后加个快速幂就好

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long ll;
    ll ans[70],n,dp[70][70][70];
    ll num[70];
    const ll mod=10000007;
    
    inline ll dfs(int pos,int now,int goal,bool limit)
    {
        if(pos==0&&now==goal) return 1;
        if(pos==0) return 0;
        if(!limit&&dp[pos][now][goal]!=-1) return dp[pos][now][goal];
        int up=1; ll tot=0;
        if(limit) up=num[pos];
        for(register int i=0;i<=up;++i)
        {
            if(i==1) tot+=dfs(pos-1,now+1,goal,limit&&(i==num[pos]));
            else tot+=dfs(pos-1,now,goal,limit&&(i==num[pos]));
        } 
        if(!limit) dp[pos][now][goal]=tot;
        return tot;
    }
    
    inline ll quick_pow(ll x,ll y)
    {
        if(y==0) return 1;
        if(y==1) return x%mod;
        if(y%2==0)
        {
            ll tmp=quick_pow(x,y/2)%mod;
            return tmp*tmp%mod;
        }
        if(y%2!=0)
        {
            ll tmp=quick_pow(x,y/2)%mod;
            return x%mod*tmp*tmp%mod;
        } 
    }
    
    inline ll solve(ll k)
    {
        int pos=0;
        while(k>0)
        {
            num[++pos]=k&1;
            k=k>>1;
        }
        for(register int i=1;i<=60;++i)
            ans[i]=dfs(pos,0,i,true);
        ll res=1;
        for(register int i=2;i<=60;++i)
            res=(res*quick_pow(i,ans[i]))%mod;
        return res;
    }
    
    int main()
    {
        scanf("%lld",&n);
        memset(dp,-1,sizeof(dp));
        printf("%lld
    ",solve(n));
        return 0;
    }
  • 相关阅读:
    kill命令
    linux grep命令
    ps命令详解
    Linux chmod命令详解
    Linux netstat命令详解
    多线程同步机制的几种方法
    C++_运算符重载 总结
    malloc/free与new/delete的区别
    python发送邮件
    linux之nfs
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11840666.html
Copyright © 2011-2022 走看看