1 条题解

  • 0
    @ 2025-8-24 23:14:43

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 寄风
    现实中的你,是否很成功?

    搬运于2025-08-24 23:14:43,当前版本为作者最后更新于2025-04-25 21:02:22,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    upd on 2025.6.5 修正了一个笔误,感谢

    https://www.luogu.com.cn/user/225375

    场切并获得了首 A。

    挺好的锻炼脑力题。

    考虑推一个柿子,那么:

    a2+b2+c2+d2=abcd\sqrt{a^2+b^2+c^2+d^2}=a\oplus b\oplus c\oplus d a2+b2+c2+d2=(abcd)2a^2+b^2+c^2+d^2=(a\oplus b\oplus c\oplus d)^2

    因为 x>0,x2>0\forall{x>0},x^2>0,所以 (abcd)>d(a\oplus b\oplus c\oplus d)>d

    (abcd)=d+x(a\oplus b\oplus c\oplus d)=d+x

    那么我们考虑把柿子拆开:

    a2+b2+c2+d2=(d+x)2a^2+b^2+c^2+d^2=(d+x)^2 a2+b2+c2+d2=d2+2×x×d+x2a^2+b^2+c^2+d^2=d^2+2\times x\times d+x^2 a2+b2+c2=2×x×d+x2a^2+b^2+c^2=2\times x\times d+x^2

    获得了这个之后我们该怎么做?

    首先任意一个 xx 我们都可以构造,设 log2(x)+1=y\log_{2}(x)+1=y,那么我们让 dd 的后 yy 位都是 00,然后 abca\oplus b\oplus c 就是 xx 就可以了。

    那么你发现 xx 越小构造难度应该也是越小的。

    那么先令 x=0x=0,那么 a2+b2+c2=0a^2+b^2+c^2=0,显然是不可以的。

    那么考虑让 x=1x=1

    那么我们获得了两个条件,就是 abc=1a\oplus b\oplus c=1a2+b2+c2=2×d+1a^2+b^2+c^2=2\times d+1;同时我们还获得了一个约束,就是 dmod2d \bmod 2 必须是 00

    保险起见,我们先把 a=1a=1 判掉,这个直接写个暴力找解即可。

    那么因为 abc=1a\oplus b\oplus c=1aa 又大于 11,所以如果 aa 的最高位和 b,cb,c 的最高位相同我们是不好构造的。所以我们只能考虑从比 aa 的最高位更高的位入手,设 aa 的最高位是第 qq 位,那么 bbcc 的第 q+1q+1 位都是 11 就可以了。

    然后因为我们要保证 a<b<ca<b<c,所以我们考虑将 bb 的第 qq 位置为 00,将 cc 的第 qq 位置为 11 就可以了。

    那么剩下的位的话,因为二进制的按位考虑,所以我们可以将 bb 的第 00 位到第 q1q-1 位都设成和 aa 一样,这样子 aba\oplus b 就是 2q+2q+12^q+2^{q+1} 了。

    那么我们再将 cc 的第 00 位置 11 就可以满足 abc=1a\oplus b\oplus c=1 了。

    dd 的求法就是 d=a2+b2+c212d=\frac{a^2+b^2+c^2-1}{2}

    这显然满足 c<dc<d

    总结下,就是构造 b=a+2q,c=2q+1+2q+1b=a+2^q,c=2^{q+1}+2^q+1 即可。

    那么看上去对完了?这真的是对的吗?

    这个正确性非常显然,用屁股都能想到。

    写一发,结果

    其实这个做法是错的

    为啥会错呢?我们发现我们上面推导的一切,都有一个前提:dmod2d \bmod 2 必须是 00。而我们上面并没有保证 dmod2d \bmod 200

    难道我们的努力白费了?

    并不是。

    我们考虑 dmod2d \bmod 200 的限制,也就是说 d2mod4d^2 \bmod 4 必须是 00,也就是说 d2mod4+1d^2 \bmod 4+1 必须是 11

    在我们上面的构造中,我们保证了 ba(mod2)b \equiv a \pmod 2cmod2=1c \bmod 2=1

    所以如果 amod2=0a \bmod 2=0,那么带回原式,我们的构造是有效的,a2mod4=0a^2\bmod 4=0b2mod4=0b^2\bmod 4=0c2mod4=1c^2\bmod 4=1a2+b2+c22×d+1(mod4)a^2+b^2+c^2 \equiv 2\times d+1 \pmod 4

    但是如果 amod2=1a \bmod 2=1 我们的构造就无效了。

    考虑将 bbcc 进行微调,由于 amod2=1a \bmod 2=1,所以如果我们将 bbcc 的值同时减小 11 的话,并不会影响 abca\oplus b\oplus c 的结果。

    重新带回,当 amod2=1a \bmod 2=1 时,a2mod4=1a^2\bmod 4=1b2mod4=0b^2\bmod 4=0c2mod4=0c^2\bmod 4=0a2+b2+c22×d+1(mod4)a^2+b^2+c^2 \equiv 2\times d+1 \pmod 4

    那么就做完了,不难证明大小关系依然满足 a<b<c<da<b<c<d

    代码:

    #include <bits/stdc++.h>
    
    using i64 = long long;
    using u64 = unsigned long long;
    using u32 = unsigned;
    using i128 = __int128;
    using u128 = unsigned __int128;
    
    i64 a, b, c, d;
    
    inline void debug() {
        std::cerr << "check:\n";
    
        std::cerr << a * a + b * b + c * c + d * d << '\n';
    
        std::cerr << (a ^ b ^ c ^ d) * (a ^ b ^ c ^ d) << '\n';
    }
    
    int main() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr), std::cout.tie(nullptr);
    
        std::cin >> a;
    
        if (a == 1) {
            for (int b = a + 1; b <= 500; b++) {
                for (int c = b + 1; c <= 500; c++) {
                    for (int d = c + 1; d <= 500; d++) {
                        int xx = (a ^ b ^ c ^ d);
                        if (a * a + b * b + c * c + d * d == xx * xx) {
                            std::cout << b << ' ' << c << ' ' << d << '\n';
                            return 0;
                        }
                    }
                }
            }
            std::cout << -1 << '\n';
            return 0;
        }
    
        //b=a+(1<<q),c=(1<<(q+1))+(1<<q)+1
        
        int q = std::__lg(a);
    
        if (a % 2 == 0) {
            b = a + (1ll << q), c = (1ll << (q + 1)) + (1ll << q) + 1;
    
            d = (a * a + b * b + c * c - 1) / 2;
            //我靠,要保证 d 最后一位是 0
    
            if (d % 2 == 0) {
                std::cout << b << ' ' << c << ' ' << d << '\n';
                debug();
                return 0;
            } 
            assert(0);
        } else {
            b = a + (1ll << q) - 1, c = (1ll << (q + 1)) + (1ll << q);
    
            d = (a * a + b * b + c * c - 1) / 2;
            //我靠,要保证 d 最后一位是 0
    
            if (d % 2 == 0) {
                std::cout << b << ' ' << c << ' ' << d << '\n';
                debug();
                return 0;
            } 
            exit(114);
        }
    
        // for (int d = c + 1; d <= 100000; d++) {
        //     int xx = (a ^ b ^ c ^ d);
        //     if (a * a + b * b + c * c + d * d == xx * xx) {
        //         std::cout << d << '\n';
        //         return 0;
        //     }
        //     std::cerr << a * a + b * b + c * c + d * d << " " << xx * xx << '\n';
        // }
    
        // std::cout << a << ' ' << b << ' ' << c << ' ' << d << '\n';
    
        // std::cerr << (a ^ b ^ c) << ' ' << a * a + b * b + c * c << '\n';
    
        return 0;
    }
    

    有心路历程的代码,大家可以看看我赛时心态。

    • 1

    信息

    ID
    10775
    时间
    1000ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者