1 条题解
-
0
自动搬运
来自洛谷,原作者为

CaoXian
这是我初一的成就,也是我最后的成就,几年学习终究是证明了自己的上限搬运于
2025-08-24 22:50:59,当前版本为作者最后更新于2023-10-05 15:09:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
出题人题解。
原本预估的难度是黄,但是从反馈来看的话难度是绿(
题意应该很清楚,我的解法是推式子+缩放,一些奇怪的方法可以看 Super_Cube 的题解。
$$\begin{aligned} &\dfrac{\dfrac{n \times (n + 1)}{2} - m}{n - 1}\\ =&\dfrac{n \times (n + 1) - 2 \times m}{2 \times (n - 1)}\\ =&\dfrac{n \times (n - 1) + 2 \times n - 2 \times m}{2 \times (n - 1)}\\ =&\dfrac{n}{2} + \dfrac{n - m}{n - 1}\\ =&a + \dfrac{b}{c}\\ \end{aligned} $$接下来是缩放,也是我认为的这一道题最精彩的部分。
注意到 ,所以 。
所以 。
带入到上面的式子后就是:
$$\dfrac{n}{2} \leqslant \dfrac{n}{2} + \dfrac{n - m}{n - 1} = a + \dfrac{b}{c} \leqslant \dfrac{n}{2} + 1 $$因为 是最简真分数(也就是小于 ),所以又有:
把它拆成两个不等式并化简:
$$\begin{cases} n < 2\times a + 2\\ 2 \times a - 2 \leqslant n \end{cases} $$(因为 是正整数,所以 等价于 )
最后就得到了:$2 \times a - 2 \leqslant n \leqslant 2 \times a + 1$。
于是可以在这个范围枚举 ,也就带一个四倍的常数。
得到了之后带回最初的式子就可以得到 的值,也就是:
$$\begin{aligned} \dfrac{\dfrac{n \times (n + 1)}{2} - m}{n - 1}&= \dfrac{a \times c + b}{c}\\ \dfrac{n \times (n + 1)}{2} - m&= \dfrac{(n - 1) \times (a \times c + b)}{c}\\ m&= \dfrac{n \times (n + 1)}{2} - \dfrac{(n - 1) \times (a \times c + b)}{c}\\ \end{aligned} $$因为 也是正整数,所以要检查一下 能不能整除 。
要注意上面的式子算出来的 仍然可能不合法(比如出现负数),以及 时 但是 要判断一下。
运算过程中变量可能超
long long,记得开__int128还有优化运算顺序。最后给出代码:
#include <bits/stdc++.h> using namespace std; #define getchar gc typedef __int128 ll; #define fu(i, l, r) for(ll i = l; i <= r; ++i) char gc() {static char ibuf[1 << 20], *p1 = ibuf, *p2 = ibuf; return p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, 1000010, stdin), p1 == p2) ? -1 : *p1++;} void read(ll& x) {x = 0; int f = 1; char ch = getchar(); while(ch < '0' || ch > '9') f *= ((ch == '-') ? -1 : 1), ch = getchar(); while(ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); x *= f;} ll t, m, a, b, c; int main() { read(t); while(t--) { read(a), read(b), read(c); fu(i, max(2 * a - 2, (ll)2), 2 * a + 1) { if((i - 1) % c) continue; m = i * (i + 1) / 2 - (i - 1) / c * (a * c + b); if(m < 1 || m > i) continue; printf("%lld %lld\n", (long long)i, (long long)m); break; } } return 0; }
- 1
信息
- ID
- 7385
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者