CodeForces - 628D (數位dp)
Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in decimal presentation of the number on even positions and nowhere else.
For example, the numbers 1727374, 17, 1 are 7-magic but 77, 7, 123, 34, 71 are not 7-magic. On the other hand the number 7 is 0-magic, 123 is 2-magic, 34 is 4-magicand 71 is 1-magic.
Find the number of d-magic numbers in the segment [a, b] that are multiple of m. Because the answer can be very huge you should only find its value modulo 109 + 7 (so you should find the remainder after dividing by 109 + 7).
Input
The first line contains two integers m, d (1 ≤ m ≤ 2000, 0 ≤ d ≤ 9) — the parameters from the problem statement.
The second line contains positive integer a in decimal presentation (without leading zeroes).
The third line contains positive integer b in decimal presentation (without leading zeroes).
It is guaranteed that a ≤ b, the number of digits in a and b are the same and don't exceed 2000.
Output
Print the only integer a — the remainder after dividing by 109 + 7 of the number of d-magic numbers in segment [a, b] that are multiple of m.
Examples
Input
2 6 10 99
Output
8
Input
2 0 1 9
Output
4
Input
19 7 1000 9999
Output
6
題目大意:
求一個區間內某種數的個數,需要是m的倍數,並且奇數位不能包含d,偶數為必須包含d。數的位數是2000位。
思路:
首先是數位dp。
關於m的限制,直接便計算邊取模就行。d限制,需要分奇偶討論一下。
數的位數很大,需要用字串,這樣的話,閉區間,左邊的數減一不好計算,需要特判一下。
程式碼:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <cmath>
#include <ctime>
using namespace std;
#define ll long long
const int mod=1e9+7;
long long a[2200];
long long dp[2200][2100][2];
int m, id;
int l;
long long dfs(int pos, int sum, int jo,int limit)
{
if (pos == -1)
{
return !sum&&jo;
}
if (!limit&&dp[pos][sum][jo] != -1)return dp[pos][sum][jo];
long long sun = 0;
int end = limit ? a[pos] : 9;
for (int i = 0;i <= end;i++)
{
if ((l-pos)%2==0)
{
sun = (sun+dfs(pos - 1, (sum*10 + i) % m,jo&&(i==id), limit&&i == a[pos]))%mod;
}
else
{
sun = (sun+dfs(pos - 1, (sum*10 + i) % m, (jo&&!(i==id)),limit&&i == a[pos]))%mod;
}
}
if (!limit)dp[pos][sum][jo] = sun;
return sun;
}
long long go(char x[])
{
int pos = strlen(x);
l=pos;
memset(a,0,sizeof(a));
for(int i=0;i<pos;i++)
{
a[pos-i-1]=x[i]-'0';
}
return dfs(pos - 1, 0, 1,1);
}
char b[2200],c[2200];
int pan(char x[])
{
int pos = strlen(x);
int sum=0;
int flag=0;
int flag1=0;
for(int i=0;i<pos;i++)
{
int v=x[i]-'0';
sum=(sum*10+v)%m;
if(i%2==1)
{
if(v!=id)
{
flag=1;
break;
}
}
else
{
if(v==id)
{
flag1=1;
break;
}
}
}
if(!sum&&!flag&&!flag1)return 1;
else return 0;
}
int main()
{
scanf("%d%d", &m, &id);
scanf("%s%s", b, c);
memset(dp, -1, sizeof(dp));
printf("%lld\n", (go(c)-go(b)+pan(b)+mod)%mod);
return 0;
}
相關文章
- [DP] 數位DP
- 數位 dp
- 數位dp - 板子題
- 數位DP小記
- #數位DP 計數問題
- 數位DP 學習筆記筆記
- 學習筆記:數位dp筆記
- 【學習筆記】數位DP筆記
- 1082. 數字遊戲 (數位DP)遊戲
- POJ3252Round Numbers(數位dp)
- 演算法隨筆——數位DP演算法
- BZOJ 2425 [HAOI2010]計數:數位dp + 組合數
- BZOJ 3329 Xorequ:數位dp + 矩陣快速冪矩陣
- BZOJ3329: Xorequ(二進位制數位dp 矩陣快速冪)矩陣
- [筆記]數位dp例題及詳解(更新中)筆記
- Codeforces 11D A Simple Task 題解 [ 藍 ] [ 狀壓 dp ]
- Educational Codeforces Round 167 (Rated for Div. 2) D(dp,貪心)
- 計數類 DP
- 數位 dp / lianggj 讓你學小專題應該怎麼辦
- HDU 6415 (計數dp)
- 合法方案數(dp)
- 【CodeForces】 Codeforces Round #672 (Div. 2) B.Rock and Lever (思維&位運算)
- Divisibility 【數學計數】Codeforces 597A
- dp 套 dp(dp of dp)小記
- Tricky Sum【數學】CodeForces 598A
- 如何提升自己的Codeforces分數
- 四位整數位數拆分
- DP套DP
- AtCoder Beginner Contest 370 E(計數 + DP)
- 幸運數(dp+矩陣加速)矩陣
- 巨大的數(dp+矩陣加速)矩陣
- codeforces 1216E1(數學+暴力)
- 【DP】Educational DP Contest
- 樹上的等差數列 [樹形dp]
- 計數 dp 做題記錄(日更)
- bzoj3930: [CQOI2015]選數(Dp)
- 整數劃分(硬幣問題)(dp)
- JavaScript保留兩位或者其他位數小數JavaScript