• bzoj 3209 bzoj1799 数位dp


     

    3209: 花神的数论题

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2267  Solved: 1040
    [Submit][Status][Discuss]

    Description

    背景
    众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
    描述
    话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
    花神的题目是这样的
    设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
    派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。

    Input

    一个正整数 N。

    Output

    一个数,答案模 10000007 的值。

    Sample Input

    样例输入一

    3

    Sample Output

    样例输出一

    2

    HINT



    对于样例一,1*1*2=2;


    数据范围与约定


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

    // 数位dp模板题 10^15最多52个1,枚举1的个数来统计就行了。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const ll mod=1e7+7;
    int bit[60],maxv;
    ll dp[60][60];
    ll pow_mod(ll a,ll b)
    {
        if(b==0) return 1;
        ll x=pow_mod(a,b/2);
        ll ans=x*x%mod;
        if(b&1) ans=ans*a%mod;
        return ans;
    }
    ll dfs(int pos,int x,int limt)
    {
        if(pos<=0) return x==maxv;
        if(!limt&&dp[pos][x]!=-1) return dp[pos][x];
        ll ans=0;
        int maxb=(limt?bit[pos]:1);
        for(int i=0;i<=maxb;i++){
            ans+=dfs(pos-1,x+i,limt&&(i==maxb));
        }
        if(!limt) dp[pos][x]=ans;
        return ans;
    }
    void solve(ll n)
    {
        int nu=0;
        while(n){
            bit[++nu]=(n&1);
            n>>=1;
        }
        ll ans=1;
        for(int i=1;i<=nu;i++){
            memset(dp,-1,sizeof(dp));
            maxv=i;
            ll tmp=dfs(nu,0,1);
            ans=ans*pow_mod(i,tmp)%mod;
        }
        printf("%lld
    ",ans);
    }
    int main()
    {
        ll n;
        scanf("%lld",&n);
        solve(n);
        return 0;
    }

    1799: [Ahoi2009]self 同类分布

    Time Limit: 50 Sec  Memory Limit: 64 MB
    Submit: 1245  Solved: 535
    [Submit][Status][Discuss]

    Description

    给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。

    Input

     

    Output

     

    Sample Input

    10 19

    Sample Output

    3

    HINT

    【约束条件】1 ≤ a ≤ b ≤ 10^18

    代码:
    //数位dp模板题 10^18的数数位和最大是153,然后枚举数位和然后就行了。刚开始还傻到想要求前153个数的lcm。。。。
    //dfs时记录余数pre 和数位和sum。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    ll dp[20][200][200],po[20];
    int bit[20];
    ll dfs(int pos,int mod,int sum,int pre,bool w){
        if(pos<=0) return pre==0&&sum==mod;
        if(!w&&dp[pos][sum][pre]!=-1) return dp[pos][sum][pre];
        ll ans=0;
        int maxb=(w?bit[pos]:9);
        for(int i=0;i<=maxb;i++){
            ans+=dfs(pos-1,mod,sum+i,(pre+i*po[pos])%mod,w&&(i==maxb));
        }
        if(!w) dp[pos][sum][pre]=ans;
        return ans;
    }
    ll solve(ll x)
    {
        int nu=0;
        while(x){
            bit[++nu]=x%10;
            x/=10;
        }
        ll ans=0;
        for(int mod=1;mod<=nu*9;mod++){
            memset(dp,-1,sizeof(dp));
            ans+=dfs(nu,mod,0,0,1);
        }
        return ans;
    }
    int main()
    {
        po[1]=1;
        for(int i=2;i<=18;i++) po[i]=po[i-1]*1LL*10;
        ll a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld
    ",solve(b)-solve(a-1));
        return 0;
    }
  • 相关阅读:
    Oracle中的to_date参数含义
    Oracle 中 IW和WW 有何差别
    iBaits.Net(1):简介与安装
    带你逛逛诺基亚芬兰总部:满满都是回忆啊
    LINQ的分组聚合技术
    WPF的Docking框架 ——AvalonDock
    iBatis.Net(3):创建SqlMapper实例
    iBatis.Net(2):基本概念与配置
    C#异步编程及其同步机制
    web使用
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/7384391.html
Copyright © 2020-2023  润新知