• BZOJ 1799 同类分布(数位DP)


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

    注意到各位数字之和最大是153.考虑枚举这个东西。那么需要统计的是[0,a-1]和[0,b]内各位数字之和为x且能整除x的数字个数。

    那么我们只需要数位dp一波即可。

    令dp[pos][i][x]表示有pos位且数字之和为x的数mod P=i的数字个数。

    则转移方程显然可得。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi acos(-1.0)
    # define eps 1e-9
    # define MOD 1024523
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    int Scan() {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=55;
    //Code begin...
    
    LL dp[20][165][165], p[20];
    int wei[20];
    
    LL dfs(int pos, int mod, int limit, int x, int P){
        if (x<0) return 0;
        if (pos==0) return mod==0&&x==0;
        if (!limit&&~dp[pos][mod][x]) return dp[pos][mod][x];
        int up=limit?wei[pos]:9;
        LL res=0;
        FOR(i,0,up) res+=dfs(pos-1,(mod+P-(i*p[pos-1]%P))%P,limit&&i==wei[pos],x-i,P);
        if (!limit) dp[pos][mod][x]=res;
        return res;
    }
    LL sol(LL x){
        int pos=0;
        while (x) wei[++pos]=x%10, x/=10;
        LL res=0;
        int top=min(162,pos*9);
        FOR(i,1,top) mem(dp,-1), res+=dfs(pos,0,1,i,i);
        return res;
    }
    int main ()
    {
        LL a, b;
        p[0]=1; FO(i,1,20) p[i]=p[i-1]*10;
        scanf("%lld%lld",&a,&b);
        printf("%lld
    ",sol(b)-sol(a-1));
        return 0;
    }
    View Code
  • 相关阅读:
    MVC3分页传2参
    C# 二进制存储图片到mssql(一)
    著名黑客组织[转]
    浅看C# md5加密
    google搜索技巧
    字符串编码转换 GBK utf8
    objectivec 中随机数的用法 (3种:arc4random() 、random()、CCRANDOM_0_1() )
    NSPredicate的用法
    Java关键字final、static使用总结()
    CGAffineTransform相关函数
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6792481.html
Copyright © 2020-2023  润新知