CF980D Perfect Groups Sol

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

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

显然对于组大小 siz=2,有 xy 为平方数才能满足为同一组。

考虑拓展到 siz>2 的情况。

假设当前 x=piki, y=PiKi,且 xy 为平方数。

那么有,对于相同的质因子 pi,Pj,有 [ki+Kj0 (mod 2)]

对于不同的质因子 pi,有 [ki0 (mod 2)]。对于 Pj 同理。

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

现在探讨 y,z 匹配是否合法。令 z=gili

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

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

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

拿并查集维护它的性质即可。复杂度 O(n2logn)

#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 @   MistZero  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示