#include #include #include #include //#include #include #include #include #include #include //#include #include #include #include //#include #include #include //#include #include #include #include #include const int dx[] = {1, 0, -1, 0}; const int dy[] = {0, 1, 0, -1}; using namespace std; typedef long long ll; typedef vector vi; typedef vector vll; typedef pair pii; const ll MOD = 1e9+7; const int MAXN = 200020; ll dp[MAXN][2][2][3]; // n, big, exist3, mod3 ll memo1[10][2][2][3][800]; // n, big, exist3, mod3, modP ll memo2[10][2][3][800]; // n, exist3, mod3, modP ll memo[2][2][3]; // すでにbigと決定, exist3, mod3 int check(string A, int P) { int sum = 0, exist3 = 0, modP = 0; for (char c : A) { int num = c-'0'; sum += num; exist3 |= (num==3); modP = (modP*10+num)%P; } if (modP) { if (sum%3 == 0 || exist3) return 1; } return 0; } ll calc(string s, int P) { if (s.size() <= 5) { int A = stoi(s); ll ans = 0; for (int i = 0; i <= A; i++) { if (check(to_string(i), P)) ans++; } return ans; } memset(memo1, 0, sizeof(memo1)); memset(memo2, 0, sizeof(memo2)); memset(memo, 0, sizeof(memo)); memset(dp, 0, sizeof(dp)); int n = s.size(); string t = s.substr(n-5); // memo1 を求める memo1[0][0][0][0][0] = 1; for (int i = 0; i < 5; i++) for (int big = 0; big < 2; big++) { for (int e3 = 0; e3 < 2; e3++) for (int m3 = 0; m3 < 3; m3++) for (int mp = 0; mp < P; mp++) { if (big) { for (int j = 0; j < 10; j++) { int nm3 = (m3+j)%3, nmp = (mp*10+j)%P; int ne3 = e3; ne3 |= (j==3); memo1[i+1][big][ne3][nm3][nmp] += memo1[i][big][e3][m3][mp]; memo1[i+1][big][ne3][nm3][nmp] %= MOD; } } else { int num = t[i]-'0'; for (int j = 0; j <= num; j++) { int nm3 = (m3+j)%3, nmp = (mp*10+j)%P; int ne3 = e3; ne3 |= (j==3); int nbig = (j> A >> B >> P; ll ans = calc(B, P)-calc(A, P)+check(A, P); ans = (ans%MOD + MOD) % MOD; cout << ans << endl; return 0; }