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 1≤ai≤106 。每一秒过后,数组每个元素 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)x⋅y ,如果这个数是完全平方数,当且仅当 x ⋅ y x\cdot y x⋅y 是完全平方数。所以 x x x 与 y y y 相邻当且仅当 x ⋅ y x\cdot y x⋅y 是一个完全平方数。
- 把 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;
}
}