bzoj 1799: [Ahoi2009]self 同类分布 数位dp

1799: [Ahoi2009]self 同类分布

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

Description

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

Input

 

Output

 

Sample Input

10 19

Sample Output

3

HINT

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

Source

Day1

 类似hdu 4389

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-4
#define bug(x)  cout<<"bug"<<x<<endl;
const int N=1e5+10,M=1e6+10,inf=2147483647;
const ll INF=1e18+10,mod=2147493647;
ll f[20][200][200],bit[11];
ll dp(int pos,int sum,int m,int p,int flag)
{
    if(pos==0)return (sum==p&&m==0);
    if(flag&&f[pos][sum][m]!=-1)return f[pos][sum][m];
    int x=flag?9:bit[pos];
    ll ans=0;
    for(int i=0;i<=x;i++)
    {
        ans+=dp(pos-1,sum+i,(m*10+i)%p,p,flag||i<x);
    }
    if(flag)f[pos][sum][m]=ans;
    return ans;
}
ll getans(ll x,int p)
{
    int len=0;
    while(x)
    {
        bit[++len]=x%10;
        x/=10;
    }
    return dp(len,0,0,p,0);
}
int main()
{
    ll l,r;
    scanf("%lld%lld",&l,&r);
    ll ans=0;
    for(int i=1;i<=162;i++)
    {
        memset(f,-1,sizeof(f));
        ans+=getans(r,i)-getans(l-1,i);
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2017-03-20 19:44  jhz033  阅读(193)  评论(0编辑  收藏  举报