1 条题解

  • 0
    @ 2025-8-24 22:50:59

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 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} $$

    接下来是缩放,也是我认为的这一道题最精彩的部分。

    注意到 1mn1 \leqslant m \leqslant n,所以 0nmn10 \leqslant n - m \leqslant n - 1

    所以 0nmn110 \leqslant \dfrac{n - m}{n - 1} \leqslant 1

    带入到上面的式子后就是:

    $$\dfrac{n}{2} \leqslant \dfrac{n}{2} + \dfrac{n - m}{n - 1} = a + \dfrac{b}{c} \leqslant \dfrac{n}{2} + 1 $$

    因为 bc\dfrac{b}{c} 是最简真分数(也就是小于 11),所以又有:

    n21<an2+1\dfrac{n}{2} - 1 < a \leqslant \dfrac{n}{2} + 1

    把它拆成两个不等式并化简:

    $$\begin{cases} n < 2\times a + 2\\ 2 \times a - 2 \leqslant n \end{cases} $$

    (因为 nn 是正整数,所以 n<2×a+2n < 2\times a + 2 等价于 n2×a+1n \leqslant 2\times a + 1

    最后就得到了:$2 \times a - 2 \leqslant n \leqslant 2 \times a + 1$。

    于是可以在这个范围枚举 nn,也就带一个四倍的常数。

    nn 得到了之后带回最初的式子就可以得到 mm 的值,也就是:

    $$\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} $$

    因为 mm 也是正整数,所以要检查一下 cc 能不能整除 n1n - 1

    要注意上面的式子算出来的 mm 仍然可能不合法(比如出现负数),以及 a=1a = 12×a2=02 \times a - 2 = 0 但是 n2n \geqslant 2 要判断一下。

    运算过程中变量可能超 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
    上传者