1 条题解

  • 0
    @ 2026-10-26 23:48:27

    思路与算法

    令t=D-C,则B=A+2t、C>=A+8t+1。按t枚举,用频次计算AB对前缀和、CD对后缀和,一次扫描同时累计每个数值在A/B/C/D四个角色的逐件计数。

    正确性说明

    固定t后AB和CD两对独立,只受C>=A+8t+1的分离限制。对A/B角色乘另一个AB值频次及合法CD后缀对数;对C/D角色乘另一CD值频次及合法AB前缀对数,恰为固定这一件物品后的其余三件选择数。逐t互斥且覆盖所有魔法阵,所以累加正确。

    复杂度

    O(n²/9+m)时间、O(n+m)空间,含频次、四角色数组初始化与输出;实际枚举长度和约n²/18。

    易错点

    除以3按实数不等式解释,等价3(B-A)<C-B,不能先整除截断。给某一物品输出时,不再乘它自身值的频次;重复数值的不同编号仍有独立选择。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, m;
        cin >> n >> m;
        vector<long long> f(n + 1);
        vector<int> a(m);
        for (int &v : a) {
            cin >> v;
            f[v]++;
        }
        vector<array<long long, 4>> ans(n + 1);
        for (int t = 1; 9 * t + 2 <= n; t++) {
            long long suf = 0, pref = 0;
            for (int c = 8 * t + 2; c <= n - t; c++)
                suf += f[c] * f[c + t];
            for (int a = 1; a <= n - 9 * t - 1; a++) {
                int b = a + 2 * t, c = a + 8 * t + 1, d = c + t;
                ans[a][0] += f[b] * suf;
                ans[b][1] += f[a] * suf;
                suf -= f[c] * f[d];
                pref += f[a] * f[b];
                ans[c][2] += f[d] * pref;
                ans[d][3] += f[c] * pref;
            }
        }
        for (int v : a)
            cout << ans[v][0] << ' ' << ans[v][1] << ' ' << ans[v][2] << ' ' << ans[v][3] << "\n";
    }
    
    • 1

    信息

    ID
    1943
    时间
    1000ms
    内存
    256MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者