CF897B Chtholly's request 题解

Content

我们将长度为偶数的回文数称作 zcy 数,比如 \(11,1221\) 是 zcy 数,而 \(34,121\) 不是。假设第 \(i\) 个 zcy 数为 \(a_i\),求 \(\sum\limits_{i=1}^na_i\)(前 \(n\) 个 zcy 数的和)模 \(p\) 后的结果。

数据范围:\(1\leqslant n\leqslant 10^5,1\leqslant p\leqslant 10^9\)

Solution

在写题解之前做一个提醒:这篇题解里的代码用 C++11 及以下的语言提交会出现 WA 的情况,需要用 C++14 及以上的语言提交。 有可能是因为 C++14 及以上的语言里面的语句和 C++14 以下的语言的对应语句的效果不同。

以下是正文:

由于无论什么数乘以 \(2\) 都是偶数,所以我们很容易发现,第 \(i\) 个 zcy 数,即第 \(i\) 个长度为偶数的回文数,其实就相当于将 \(i\)\(i\) 反转过后的数拼接在一起得到的数,所以,我们考虑直接暴力求出 \(i\) 翻转后得到的数 \(i'\),然后设数字 \(x\) 的长度为 \(L_x\),那么第 \(i\) 个 zcy 数就可以这样表示:\(10^{L_x}\times i+i'\),然后直接暴力加,边加边取模即可。

如果您去 CF 官网上看这道题目的标签的话,你会发现里面有个“暴力”的标签,所以这道题目总的来说就是一点:暴力。

Code

ll ans;
int n, m;

ll digitnum(ll x) {
	ll p = x, ans = 0;
	while(p) {
		ans++;
		p /= 10;
	}
	return ans;
}
ll turn(ll x) {
	ll p = x, ans = 0, digit[27] = {0};
	while(p) {
		digit[++digit[0]] = p % 10;
		p /= 10;
	}
	_forll(i, 1, digit[0])	ans += digit[i] * (ll)pow(10, digit[0] - i);
	return ans;
}

int main() {
	//This program is written in Windows 10 by Eason_AC
	getint(n), getint(m);
	_for(i, 1, n) {
		int len = digitnum(i), rev = turn(i);
		ll tmp = ((ll)pow(10, len) * i + rev) % m;
		ans = (ans + tmp % m) % m;
	}
	writell(ans);
	return 0;
}
posted @ 2021-12-16 15:15  Eason_AC  阅读(43)  评论(0)    收藏  举报