Amr doesn't like Maths as he finds it really boring, so he usually sleeps in Maths lectures. But one day the teacher suspected that Amr is sleeping and asked him a question to make sure he wasn't.
First he gave Amr two positive integers n and k. Then he asked Amr, how many integer numbers x > 0 exist such that:
- Decimal representation of x (without leading zeroes) consists of exactly n digits;
- There exists some integer y > 0 such that:
-
;
- decimal representation of y is a suffix of decimal representation of x.
-
As the answer to this question may be pretty huge the teacher asked Amr to output only its remainder modulo a number m.
Can you help Amr escape this embarrassing situation?
Input consists of three integers n, k, m (1 ≤ n ≤ 1000, 1 ≤ k ≤ 100, 1 ≤ m ≤ 109).
Print the required number modulo m.
1 2 1000
4
2 2 1000
45
5 3 1103
590
题意:有多少个n位数,它的后缀可以被k整除。
思路:dp[i][j]表示i位数中可以被k整除为j的数有多少(已经去除掉之其中后缀能被k整除的情况)。因为如果i-1位能被k整除的数前面不管加什么都可以。每次转移的时候只需要添加前面的数字即可。注意要特殊处理后面全是0的情况。
AC代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[1010][110],MOD,num[1010],ans,pow[1010];
int n,m;
int main()
{
int i,j,k;
scanf("%d%d%I64d",&n,&m,&MOD);
for(i=1;i<=9;i++)
dp[1][i%m]++;
num[0]=1;num[1]=9%MOD;pow[1]=10%m;
for(i=2;i<=n;i++)
num[i]=num[i-1]*10%MOD;
for(i=2;i<=n;i++)
pow[i]=pow[i-1]*10%m;
for(i=1;i<=n;i++)
{
ans=(ans+dp[i][0]*num[n-i]%MOD)%MOD;
for(j=1;j<m;j++)
for(k=0;k<=9;k++)
dp[i+1][(j+k*pow[i]%m)%m]=(dp[i+1][(j+k*pow[i]%m)%m]+dp[i][j])%MOD;
for(k=1;k<=9;k++)
dp[i+1][k*pow[i]%m]++;
}
printf("%I64d\n",ans);
}