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

浙公网安备 33010602011771号