Loading

P2714 四元组统计

首先我们有 SOSDP。

对于这题,\(\gcd\) 其实就是质因数向量上的 \(\min\),也可以看做是在取交集,也就是说先跑一遍高维后缀和,得到 \(f_i\) 表示 \(\gcd\)\(i\) 的倍数的方案,然后 \(f_i \leftarrow \binom{f_i}{4}\) 就是四元组的方案,然后再来一遍高维差分,做完了,\(f_1\) 就是答案。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// typedef __int128 i128;
typedef pair<int, int> pii;
const int N = 1e4 + 10, mod = 998244353;
template<typename T>
void dbg(const T &t) { cout << t << endl; }
template<typename Type, typename... Types>
void dbg(const Type& arg, const Types&... args) {
    cout << arg << ' ';
    dbg(args...);
}
namespace Loop1st {
int n, m, a[N], b[N], p[N], tot;
ll f[N];
void init() {
    for (int i = 2; i < N; i++) if (!b[i]) {
        p[++tot] = i;
        for (int j = i; j < N; j += i) b[j] = 1;
    }
}
void main() {
    while (cin >> n) {
        for (int i = 1; i <= n; i++) cin >> a[i], f[a[i]]++, m = max(m, a[i]);
        b[1] = 1;
        for (int i = 1; p[i] <= m; i++) // 我们有 10007 是质数,所以不会死循环
            for (int j = m / p[i]; j; j--) f[j] += f[j * p[i]];
        for (int i = 1; i <= m; i++) f[i] = f[i] * (f[i] - 1) * (f[i] - 2) * (f[i] - 3) / 24;
        for (int i = 1; i <= tot; i++) 
            for (int j = 1; j <= m / p[i]; j++) f[j] -= f[j * p[i]];
        cout << f[1] << '\n';
        for (int i = 1; i <= m; i++) f[i] = 0;
    }
}

}
int main() {
    // freopen("data.in", "r", stdin);
    // freopen("data.out", "w", stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    Loop1st::init();
    int T = 1;
    // cin >> T;
    while (T--) Loop1st::main();
    return 0;
}
// start coding at 16:39
// finish debugging at 16:52

posted @ 2026-01-09 16:56  循环一号  阅读(3)  评论(0)    收藏  举报