Codeforces Round #694 (Div. 2) D. Strange Definition 思维

D. Strange Definition

题意

如果 x x x y y y 满足 l c m ( x , y ) g c d ( x , y ) \frac{lcm(x,y)}{gcd(x,y)} gcd(x,y)lcm(x,y) 是完全平方数,则 x x x y y y 相邻。

给一个长度为 n n n 的数组,满足 1 ≤ a i ≤ 1 0 6 1\le a_i\le 10^6 1ai106 。每一秒过后,数组每个元素 a i a_i ai 都会替换为自身与所有与 a i a_i ai 相邻的数的乘积。定义 d i d_i di a i a_i ai 相邻的元素的个数。给出 q q q 个询问,每次询问 t t t 秒时的 m a x ( d i ) max(d_i) max(di)

题解

  • l c m ( x , y ) g c d ( x , y ) = x ⋅ y g c d 2 ( x , y ) \frac{lcm(x,y)}{gcd(x,y)}=\frac{x\cdot y}{gcd^2(x,y)} gcd(x,y)lcm(x,y)=gcd2(x,y)xy ,如果这个数是完全平方数,当且仅当 x ⋅ y x\cdot y xy 是完全平方数。所以 x x x y y y 相邻当且仅当 x ⋅ y x\cdot y xy 是一个完全平方数。
  • a i a_i ai 分解成 ∑ p i c i \sum p_i^{c_i} pici。求 m a x ( d i ) max(d_i) max(di) ,所以可以忽略偶数次幂,也就是可以除掉 a i a_i ai 的所有完全平方数。然后统计处理过后 a i a_i ai 出现的个数,初始答案就是出现的最大次数。
  • 经过 1 1 1 秒后,对于 a i a_i ai ,如果 c n t [ a i ] cnt[a_i] cnt[ai] 是偶数,那么 a i a_i ai 就会变成一个完全平方数,可以看作 1 1 1 ,所以 a i a_i ai 的次数就累加到 1 1 1 上。注意不能重复操作,需要维护一个 v i s [ ] vis[] vis[] 数组。操作一次之后再操作就不会产生影响了。

代码

#pragma region
//#pragma optimize("Ofast")
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
#define tr t[root]
#define lson t[root << 1]
#define rson t[root << 1 | 1]
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#pragma endregion
const int maxn = 3e5 + 5;
int a[maxn], cnt[maxn << 2], vis[maxn << 2];
int sqr(int x) {
    
     return x * x; }
int main() {
    
    
    int T;
    scanf("%d", &T);
    while (T--) {
    
    
        int n, q;
        scanf("%d", &n);
        int ans[2] = {
    
    0};
        rep(i, 1, n) {
    
    
            scanf("%d", &a[i]);
            for (int j = 2; sqr(j) <= a[i]; ++j) {
    
    
                while (a[i] % sqr(j) == 0) a[i] /= sqr(j);
            }
            cnt[a[i]]++;
            ans[0] = max(ans[0], cnt[a[i]]);
        }
        rep(i, 1, n) {
    
    
            if (cnt[a[i]] % 2 == 0 && a[i] != 1 && !vis[a[i]]) {
    
    
                cnt[1] += cnt[a[i]], cnt[a[i]] = 0;
                vis[a[i]] = 1;
            }
            ans[1] = max({
    
    ans[1], cnt[1], cnt[a[i]]});
        }
        scanf("%d", &q);
        while (q--) {
    
    
            ll w;
            scanf("%lld", &w);
            printf("%d\n", ans[w != 0]);
        }
        cnt[1] = 0;
        rep(i, 1, n) cnt[a[i]] = 0, vis[a[i]] = 0;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43860866/article/details/112591495