CF980D Perfect Groups

思路:

注意到若A * B和B * C都是完全平方数,则A * C也是完全平方数,就不难解答了,要特判0的情况。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 5005;
 4 int a[MAXN], par[MAXN], buf[MAXN];
 5 typedef long long ll;
 6 void init(int n)
 7 {
 8     for (int i = 0; i < n; i++) par[i] = i;
 9 }
10 int find(int x)
11 {
12     if (par[x] == x) return x;
13     return par[x] = find(par[x]);
14 }
15 void uni(int x, int y)
16 {
17     x = find(x); y = find(y);
18     if (x != y) par[x] = y;
19 }
20 bool check(int x, int y)
21 {
22     if ((ll)a[x] * a[y] < 0) return false;
23     ll tmp = (ll)a[x] * a[y];
24     ll root = sqrt(tmp);
25     return root * root == tmp;
26 }
27 int main()
28 {
29     int n;
30     while (scanf("%d", &n) != EOF)
31     {
32         for (int i = 0; i < n; i++) scanf("%d", &a[i]);
33         init(n);
34         for (int i = 0; i < n; i++)
35         {
36             for (int j = i + 1; j < n; j++)
37             {
38                 if (!a[i] || !a[j])
39                 {
40                     if (!a[i] && !a[j]) uni(i, j);
41                     else continue;
42                 }
43                 if (check(i, j)) uni(i, j);
44             }
45         }
46         vector<int> fa(n, 0), ans(n + 1, 0); 
47         int zero = -1;
48         for (int i = 0; i < n; i++) 
49         { 
50             fa[i] = find(i);
51             if (a[i] == 0) zero = i;
52         }
53         for (int i = 0; i < n; i++)
54         {
55             int cnt = 0;
56             memset(buf, 0, sizeof buf);
57             for (int j = i; j < n; j++)
58             {
59                 if (!buf[fa[j]]) { buf[fa[j]]++; cnt++; }
60                 if (cnt > 1 && zero != -1 && buf[fa[zero]]) ans[cnt - 1]++;
61                 else ans[cnt]++;
62             }
63         }
64         for (int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' ');
65     }
66     return 0;
67 }

猜你喜欢

转载自www.cnblogs.com/wangyiming/p/9028404.html
今日推荐