2026.06.01 作业 - # AT_abc460_e [ABC460E] x + y ≡ x + y
题目描述
对于正整数 \(a,b\),定义拼接运算 \(\mathrm{concat}(a,b)\):
把 \(a\)、\(b\) 分别写作十进制字符串 \(A,B\),将字符串 \(A\) 后接字符串 \(B\) 得到新串 \(C\),把字符串 \(C\) 视作十进制整数,该数值即为 \(\mathrm{concat}(a,b)\)。
举例:\(a=123,b=45\) 时,\(\mathrm{concat}(a,b)=12345\)。
给定正整数 \(N,M\),求满足下述条件的正整数有序对 \((x,y)\) 的总数:
\(1\le x\le N,1\le y\le N\),且 \(\mathrm{concat}(x,y)\equiv x+y \pmod M\)。
答案对 \(998244353\) 取余数。
共有 \(T\) 组测试用例,对每组输入分别输出答案。
输入格式
首行输入整数 \(T\),之后连续 \(T\) 行,每行两个整数 \(N、M\),代表一组询问。
输出格式
输出共 \(T\) 行,每行一个整数,为对应询问的合法数对数量模 \(998244353\) 的结果。
输入样例
4
3 2
123 456
20260530 460
123456789123456789 998244353
输出样例
3
0
922576091
422081792
样例说明
第一组 \(N=3,M=2\),合法数对:\((2,1),(2,2),(2,3)\),合计3组。
限制条件
- \(1\le T \le 10^4\)
- \(1\le N \le 10^{18}\)
- \(2\le M \le 10^9\)
- 所有输入数据均为整数
思考1 :表达式转换
题目要求满足 \(\text{concat}(x, y) \equiv x + y \pmod{M}\) 的数对 \((x, y)\) 个数,其中 \(1 \le x, y \le N\),$N $ 最大可达 \(10^{18}\)。
设 \(d(y)\)表示 \(y\) 的十进制位数,拼接操作可表示为:
代入原同余式并化简:
思考2: 方案统计
上式表明,对于固定位数的 \(y\),需要找到所有满足条件的 \(x\)。根据同余理论,上述同余式等价于:
因此,对于固定的位数 \(k = d(y)\):
-
\(x\) 的个数:是 \(\frac{M}{\gcd(M, 10^k - 1)}\)的倍数且不超过 \(N\),共有
\[cntX = \left\lfloor \frac{N}{M / \gcd(M, 10^k - 1)} \right\rfloor \] -
\(y\) 的个数:是 \(k\) 位数且不超过 \(N\) ,即为:位数为 \(k\) 的方案数 = $ min(n,10^k) >y \ge 10^{k-1}$
\[cntY = \min(N, 10^k - 1) - 10^{k-1} + 1 \]
由于 \(N \le 10^{18}\),所以 \(d(y)\) 最大为 19。因此只需枚举 \(k\) 从 1 到 19,对每个 \(k\) 计算 \(cntX \times cntY\) 并求和即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
#define ULL unsigned long long
const int MOD = 998244353;
ULL gcd(ULL a,ULL b) {
return b?gcd(b,a%b):a;
}
int main() {
int T; cin >> T;
vector<ULL> p(20); // 预处理 10^k
p[0] = 1; for(int i = 1; i <= 19; i++) p[i] = p[i - 1] * 10;
while(T--){
ULL N, M, ans = 0;
cin >> N >> M;
for(int k = 1; k <= 19; k++){
if (p[k-1] > N) break; // 超出N的范围,直接退出
ULL cntX = N /(M/gcd(M, p[k] - 1)); // x 的贡献
ULL cntY = min(N, p[k] - 1) - p[k - 1] + 1; // y 的贡献
ans = (ans + (__int128)cntX * cntY % MOD) % MOD;
}
cout << ans << endl;
}
return 0;
}
变量类型
在本题中,N 最大可达 (10^{18}),M 和 MOD = 998244353 均在 32 位整型范围内。涉及的关键变量有:
cntX:满足条件的 \(x\) 的个数,最大不超过 \(N\),即 \(\le 10^{18}\)。cntY:固定位数的 \(y\) 的个数,最大也约为 \(9\times 10^{17}\)。ans:所有 \((x,y)\) 对数对MOD取模后的累加和,最终值在 \([0, \text{MOD})\) 内。
各变量的推荐类型
| 变量 | 推荐类型 | 理由 |
|---|---|---|
cntX |
unsigned long long |
范围 \(0 \sim 2^{64}-1\approx 1.84\times 10^{19}\),足够容纳 \(10^{18}\)。无符号类型可避免负值,且移位/除法行为定义明确。 |
cntY |
unsigned long long |
同上,且计算 min(N, p[k]-1) 时不会出现负数。 |
ans |
unsigned long long 或 long long |
累加过程中多次取模,值始终小于 MOD(\(<2^{31}\)),任何 64 位有符号/无符号类型均可。推荐 unsigned long long 保持一致性。 |
乘积 cntX * cntY |
不能直接使用 64 位乘法 | 二者最大约 \(10^{18}\),乘积可达 \(10^{36}\),远超 64 位范围。必须使用 128 位乘法(GCC 的 __int128)暂存中间结果,再对 MOD 取模。 |

浙公网安备 33010602011771号