谁能救救我,玄关
查看原帖
谁能救救我,玄关
726139
残阳如血楼主2024/6/16 11:18
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
typedef long long lint;
const int N = 2e3 + 10, MOD = 1e9 + 7;

int m, d;
lint f[N][N];
std::string l, r;

std::string operator-(std::string sa, std::string sb) { // 高精度减法
	std::string res;
	if (sa < sb) std::swap(sa, sb), res.push_back('-');
	auto la = sa.size(), lb = sb.size(), lm = max(la, lb) + 5;
	std::vector<int> a(lm), b(lm), c(lm);
	for (size_t i = 0; i < la; ++i) a[i] = sa[la - i - 1] - '0';
	for (size_t i = 0; i < lb; ++i) b[i] = sb[lb - i - 1] - '0';
	for (size_t i = 0; i < lm - 1; ++i) {
		if (a[i] < b[i]) --a[i + 1], a[i] += 10;
		c[i] = a[i] - b[i];
	}
	while (c.size() > 1 && c.back() == 0) c.pop_back();
	for (long long i = c.size() - 1; ~i; --i) res.push_back(c[i] + '0');
	return res;
}

void change(std::string &s) {
	s.insert(s.begin(), ' ');
}

lint dp(const std::string &s, int pos, int p, bool lim) {
	if (pos == s.size()) return p == 0;
	if (!lim && ~f[pos][p]) return f[pos][p];
	int num = s[pos] - '0';
	lint res = 0;
	if (pos & 1) { // 奇数位
		for (int i = 0; i <= (lim ? num : 9); ++i) {
			if (i == d) continue; // 奇数位不能选 d
			(res += dp(s, pos + 1, (p * 10 + i) % m, lim & i == num)) %= MOD;
		}
	} else if (!lim || d <= num) // 偶数位且可以选 d
		(res += dp(s, pos + 1, (p * 10 + d) % m, lim & d == num)) %= MOD;
	if (!lim) f[pos][p] = res;
	return res;
}

int main() {
	std::cin >> m >> d >> l >> r, l = l - "1";
	change(l), change(r), memset(f, -1, sizeof(f));
	std::cout << dp(r, 1, 0, true) - dp(l, 1, 0, true) << std::endl;
	return 0;
}
2024/6/16 11:18
加载中...