【CodeForces 55D】Beautiful number 数位DP

来源:互联网 发布:linux rpm qa grep 编辑:程序博客网 时间:2024/05/19 00:55

Problem

https://vjudge.net/problem/CodeForces-55D

Solution

http://blog.csdn.net/lhq_er/article/details/77017024
代码更新过了,这个链接里的只能做到1018,这个能到91018

CODE

/* * @key words: digit DP * @tested on: CF 55D 1058ms * @Author: LuHaoqi  * @Date: 2017-08-11 17:22:47  * @Last Modified by: LuHaoqi * @Last Modified time: 2017-08-11 17:42:48 */#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>using namespace std;#define ll long longll pow10[22],Pow[22],dp[22][2][2520][50];int num[22],flcm[512],Map[2521],Map2[50],tmp[22],tot;int gcd(int a,int b){    return b==0?a:gcd(b,a%b);}int lcm(int a,int b){    if (a==0) return b;    else if (b==0) return a;    else return a/gcd(a,b)*b;}ll solve(ll x){    int len=0;    ll ans=0;    while (x) tmp[++len]=x%10,x/=10;    for (int i=1;i<=len;i++) num[i]=tmp[len-i+1];    memset(dp,0,sizeof(dp));    dp[0][1][0][0]=1;    for (int i=0;i<=len;i++)        for (int j=0;j<2;j++)            for (int k=0;k<2520;k++)                for (int l=0;l<tot;l++)                {                    ll p=dp[i][j][k][l];                    int pp=Map2[l];                    if (!p) continue;                    if (i==len)                     {                        if (k % pp==0) ans+=p;                        continue;                    }                    if (j==0)                    {                        for (int q=0;q<=9;q++)                            dp[i+1][0][(k+q*Pow[len-i-1])%2520][Map[lcm(pp,q)]]+=p;                                         }                    else                    {                        for (int q=0;q<num[i+1];q++)                            dp[i+1][0][(k+q*Pow[len-i-1])%2520][Map[lcm(pp,q)]]+=p;                        dp[i+1][1][(k+num[i+1]*Pow[len-i-1])%2520][Map[lcm(pp,num[i+1])]]+=p;                    }                               }    return ans;}void prepare(){    pow10[0]=Pow[0]=1;    for (int i=1;i<=18;i++) pow10[i]=pow10[i-1]*10,Pow[i]=pow10[i]%2520;    for (int i=1;i<(1<<9);i++)        for (int j=1;j<=9;j++)            if (i & (1<<j-1))                flcm[i]=lcm(flcm[i-(1<<j-1)],j);    for (int i=1;i<(1<<9);i++)        if (!Map[flcm[i]]) Map[flcm[i]]=tot++,Map2[tot-1]=flcm[i];}int main(){    prepare();    int T;    scanf("%d",&T);    while (T--)    {        ll a,b;        cin>>a>>b;        cout<<solve(b)-solve(a-1)<<endl;    }       return 0;}
原创粉丝点击