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;
    }
  • 相关阅读:
    对象生成xml
    Memcache使用指南
    java实现AES加密解密
    Log4j常用的配置说明
    java利用dom4j对任意xml的解析
    一个不错的JDBC连接池教程
    jwt介绍
    model基础操作
    图书管理系统前端
    图书管理系统后端
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11840666.html
Copyright © 2011-2022 走看看