codeforces--507D--The Maths Lecture(数位dp)

The Maths Lecture

Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d
& %I64u

Submit Status

Appoint description: 
System Crawler  (2015-01-24)

Description

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

Input consists of three integers n,?k,?m (1?≤?n?≤?1000, 1?≤?k?≤?100, 1?≤?m?≤?109).

Output

Print the required number modulo m.

Sample Input

Input

1 2 1000

Output

4

Input

2 2 1000

Output

45

Input

5 3 1103

Output

590

Hint

A suffix of a string S is a non-empty string that can be obtained by removing some number (possibly, zero) of first characters from S.

题目大意,n,k,m,问有多少个n位数(不含前导0)存在后缀是k的倍数(0不算),并将总数对m取余。

dp[i][j][0]代表i位数时,对k取余为j的,且后缀没有k‘的倍数的个数。

dp[i][j][1]代表i位数时,对k取余为j的,且后缀存在k的倍数的个数。

因为没有前导0,所以当i为n的时候,前面不能加0

如果前面加了一个数x得到的余数为j,那么当j==0&&x!= 0 的时候可以归到dp[i][x][1]中,否则为dp[i][x][0]

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
LL dp[1100][110][2] ;
LL Mod(LL a,LL k,LL b,LL m)
{
    int i , j ;
    LL temp ;
    a = a % m ;
    if( k > 9 )
    {
        i = 0 ;
        k -= 9 ;
        while( i < k-9 )
        {
            a = a*1000000000 % m ;
            i += 9 ;
        }
        for( ; i < k ; i++)
            a = a*10 % m ;
        a = (a*(1000000000)+b) % m ;
    }
    else
    {
        for(i = 0 ; i < k ; i++)
            a *= 10 ;
        a = ( a+b ) % m ;

    }
    return a ;
}
void init(int n,int m,int mod)
{
    int i , j , k ;
    LL x ;
    memset(dp,0,sizeof(dp)) ;
    for(i = 0 ; i < 10 ; i++)
    {
        if( i%m == 0 && i != 0 )
            dp[1][0][1] = (dp[1][0][1]+1) % mod ;
        else
            dp[1][i%m][0] = (dp[1][i%m][0]+1) % mod ;
    }
    for(i = 2 ; i <= n ; i++)
    {
        for(j = 0 ; j < 10 ; j++)
        {
            for(k = 0 ; k < m ; k++)
            {
                if( i == n && j == 0 ) continue ;
                x = Mod(j,i-1,k,m) ;
                if( x == 0 && j != 0 )
                    dp[i][x][1] = ( dp[i][x][1] + dp[i-1][k][0] ) % mod ;
                else
                    dp[i][x][0] = ( dp[i][x][0] + dp[i-1][k][0] ) % mod ;
                dp[i][x][1] = (dp[i][x][1] + dp[i-1][k][1] ) % mod ;
            }
        }
    }
    return ;
}
int main()
{
    LL n , m , mod , ans ;
    while( scanf("%I64d %I64d %I64d", &n, &m, &mod) != EOF )
    {
        init(n,m,mod) ;
        ans = 0 ;
        int i ;
        for(i = 0 ; i < m ; i++)
            ans = ( ans + dp[n][i][1] ) % mod ;
        printf("%I64d\n", ans) ;
    }
    return 0;
}
时间: 2024-10-04 17:01:12

codeforces--507D--The Maths Lecture(数位dp)的相关文章

CodeForces 55D Beautiful numbers(数位dp+数学)

题目链接:http://codeforces.com/problemset/problem/55/D 题意:一个美丽数就是可以被它的每一位的数字整除的数. 给定一个区间,求美丽数的个数. 显然这是一道数位dp,就是满足一个数能被所有位数的lcm整除即可. 一般都会设dp[len][mod][LCM],mod表示余数,LCM表示前len位的lcm. 但是如果直接裸mod会很复杂,于是再想lcm{0,1,2,3,4,5,6,7,8,9}=2520; 而且lcm{a,b,c,d....}{a,b,c,

Codeforces 55D. Beautiful numbers(数位DP,离散化)

Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得只需要记录搜到当前位出现了哪些数字作为状态即可,明显是假算法...感觉这是一道数位DP好题.可以这样思考:一个数要想被其各位数字分别都整除,等价于它被那些数字的LCM整除.因此记录当前位,当前数对(1~9的LCM)取模的结果,当前出现的数字的LCM这三个值作为状态才合理,即dp[pos][sum][

CodeForces - 55D Beautiful numbers (数位DP)

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful num

codeforces 55D D. Beautiful numbers(数位dp+数论)

题目链接: codeforces 55D 题目大意: 求在[l,r]中能够整除自己每个数位上的数字的数的个数. 题目分析: 首先我们能够知道如果这个数能够整除它的每个数位上的数字,那么它一定能够整除他们的最小公倍数,是充要的. 那么我们定义状态dp[i][j][k]代表i位在任意组合下得到的所有数位的数字的最小公倍数为j的每个数位上的数字之积%2520为k的方案数. 我们可以知道所有的公倍数最大不会超过2520,而且他们都是2520的约数,所以如果他们能够整除2520的余数,那么证明他们能够整除

Codeforces 54C First Digit Law 数位dp+概率dp

题目链接:点击打开链接 题意: 给定n个区间 下面n个区间 从每个区间中任选一个数.则一共选出了n个数 给出K(<=100) 问选出的n个数中 最高位是1的个数 占n个数的百分之K以上的概率是多少. 先求出对于第i个区间 ,选出的数最高位是1的概率P[i] dp[i][j] 表示前i个数选了j个最高位是1的概率. ////////////////////////////////////// //**********************************// //* ======= la

Codeforces 535B Tavas and SaDDas 数位DP

题意:good number 的定义是只有4,和 7组成  ,给你一个 good number ,问你它是第几个good number. 解题思路:预处理位数为k 的个数,然后再枚举n的位数,如果这一位为 7 那么答案就要加上 这一位为4的情况数. 解题代码: 1 // File Name: b.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月15日 星期三 00时46分48秒 4 5 #include<vector> 6 #incl

codeforces Hill Number 数位dp

http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits:  200000 KB 64-bit interger IO format:  %lld   Java class name:  Main Description A Hill Number is a number whose digits possibly rise and then possibl

[Codeforces 258B &amp; 259 D]Little Elephant and Elections 数位dp+dfs

http://codeforces.com/problemset/problem/258/B 题目大意: 说七个party选择数字(各不相同) 而规定的小象的party选择的数字之中所拥有的数字4和7的个数要比其他六个party拥有的个数之和还要严格多,询问方案数. 如m=7时其余的随意选择至少会拥有一个4或7,与题意矛盾,故方案数为0 m=8时,7 1 2 3 5 6 8是一种合法方案 思路: 由于小象的party选到的数字所含4和7的个数至多和m的位数一样多,则枚举小象的party所含4和7

Codeforces 55D (数位DP+离散化+数论)

题目链接: http://poj.org/problem?id=2117 题目大意:统计一个范围内数的个数,要求该数能被各位上的数整除.范围2^64. 解题思路: 一开始SB地开了10维数组记录情况. 首先要求能被各位上的数整除,可以转化为被一个数整除问题. 这个数就是各位上数的最小公倍数LCM(不是GCD). 其次,处理整除问题,得转化成数位DP的余数模板.1~9的LCM最大是2520, 那么%2520,让其可以开数组进行记忆化搜索. 最后, 对于不能%2520最后结果,再%各个数位累计过来的