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
类似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; }