CF980D Perfect Groups Sol

看到题,最小划分组一定有确定性方案。

考虑如果两个数 \(x,y\) 满足怎样的条件才能使其被分为同一组。

显然对于组大小 \(\text{siz}=2\),有 \(x \cdot y\) 为平方数才能满足为同一组。

考虑拓展到 \(\text{siz}>2\) 的情况。

假设当前 \(x=\prod\limits p_i^{k_i},\space y=\prod\limits P_i^{K_i}\),且 \(x \cdot y\) 为平方数。

那么有,对于相同的质因子 \(p_i,P_j\),有 \(\forall [k_i+K_j\equiv0\space(\bmod\space2)]\)

对于不同的质因子 \(p_i\),有 \(\forall [k_i\equiv0\space(\bmod\space2)]\)。对于 \(P_j\) 同理。

那么假设当前已经合并 \(x,y\),且 \(z\) 可以与 \(x\) 合并。

现在探讨 \(y,z\) 匹配是否合法。令 \(z=\prod g_i^{l_i}\)

那么对于与 \(x,y\) 共同的质因子,幂和显然为偶数,合法。

对于和 \(x,y\) 均不相同的质因子,由于和 \(x\) 合并时合法,它的幂一定本来就是偶数。

对于仅和 \(y\) 相同的质因子,由于 \(y\) 的幂本来就是偶数(因为和 \(x\) 合并时合法),且因为 \(x,z\) 合并时合法,\(z\) 的幂本来也是偶数。也就是说,\(z\) 的这个质因子若和 \(y\) 相同,偶 \(+\)\(=\) 偶,仍然合法。

拿并查集维护它的性质即可。复杂度 \(O(n^2 \log n)\)

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 5e3 + 10;
int n, cnt, a[N], res[N], fa[N]; bool vis[N];
inline int getf(int x) { return fa[x] == x? x : fa[x] = getf(fa[x]); }

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(0), cout.tie(0);
    cin >> n; for (int i = 1; i <= n; ++i) cin >> a[i], fa[i] = i;
    for (int i = 1; i < n; ++i)
        for (int j = i + 1; j <= n; ++j) {
            int tmp = a[i] * a[j]; if (tmp <= 0) continue;
            int sq = sqrt(tmp); if (sq * sq == tmp) fa[getf(i)] = getf(j);
        }
    for (int i = 1; i <= n; ++i) {
        fill(vis + 1, vis + 1 + n, false); cnt = 0;
        for (int j = i; j <= n; ++j) {
            if (!a[j]) { ++res[max(cnt, 1ll)]; continue; }
            int f = getf(j); if (!vis[f]) vis[f] = true, ++cnt;
            ++res[cnt];
        }
    }
    for (int i = 1; i <= n; ++i) cout << res[i] << ' ';
    return 0;
}
posted @ 2022-11-23 10:18  MistZero  阅读(11)  评论(0编辑  收藏  举报