#1470B - Strange Definition
题意: 给一个定义 当x和y满足 l c m ( x , y ) g c d ( x , y ) \frac{lcm(x, y)}{gcd(x, y)} gcd(x,y)lcm(x,y) 是一个完全平方数的时候,xy相关,每一轮所有互相相关的数会被替换成这些数的乘积,若干次询问问第q轮的时候,最多的互相相关的元素个数
思路: l c m ( x , y ) g c d ( x , y ) = x × y g c d ( x , y ) 2 \frac{lcm(x, y)}{gcd(x, y)} = \frac{x \times y}{gcd(x, y)^2} gcd(x,y)lcm(x,y)=gcd(x,y)2x×y
于是找 x × y x \times y x×y 是完全平方数,分解每个数,当某个因子次数是偶数时可以不考虑这个因子,次数是奇数时与次数为1无异,于是可以将数做转换,满足 x × y x \times y x×y 是完全平方数的xy转换后其实是一样的,将他们分类
当一个类里面的数的个数为偶数时,他们被替换成他们的乘积,转换后全部变成1,当一个类里面的数的个数为奇数时,替换后再转换相当于不变
于是第一轮的时候所有能转换的就都转换完了
的当询问第0轮的时候,输出最大的转换后相同的数的个数,否则输出所有合并完后最大的转换后相同的个数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 3e5 + 10;
ll a[N];
ll primes[N], cnt = 0;
bool st[N];
void sieve() {
cnt = 0;
for (ll i = 2; i < N; ++i) {
if (!st[i]) primes[++cnt] = i;
for (ll j = 1; primes[j] * i < N; ++j) {
st[primes[j] * i] = 1;
if (i % primes[j] == 0) break;
}
}
}
unordered_map<ll, ll> mp;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
sieve();
ll T;
cin >> T;
while (T--) {
mp.clear();
ll n;
cin >> n;
for (ll i = 1, x; i <= n; ++i) {
cin >> x;
ll y = 1;
for (ll j = 1; j <= cnt; ++j) {
if (primes[j] > x / primes[j]) break;
if (x % primes[j] == 0) {
ll tmp = 0;
while (x % primes[j] == 0) {
tmp++;
x /= primes[j];
}
if (tmp & 1) {
y *= primes[j];
}
}
}
if(x > 1) {
y *= x;
}
mp[y]++;
}
ll ansa = 0, ansb = 0;
for (auto x : mp) {
ansa = max(ansa, x.second);
if ((x.first == 1) || !(x.second & 1)) ansb += x.second;
}
ll q;
cin >> q;
while (q--) {
ll x;
cin >> x;
if (x == 0) {
cout << ansa << endl;
} else {
cout << max(ansa, ansb) << endl;
}
}
}
return 0;
}