题意:
数据范围:n<=3e5,a(i)<=1e6,q<=3e5,w<=1e18
解法:
l c m ( x , y ) g c d ( x , y ) = x y g c d ( x , y ) 2 x y g c d ( x , y ) 2 = x g c d ( x , y ) y g c d ( x , y ) 要 使 得 上 式 结 果 是 完 全 平 方 数 , 需 要 x 和 y 去 掉 g c d 部 分 后 相 乘 为 完 全 平 方 数 . 发 现 x 个 y 各 自 的 偶 数 次 幂 质 因 子 也 可 以 去 掉 , 不 影 响 相 乘 结 果 , 设 f ( x ) = x 去 掉 偶 数 次 幂 质 因 子 之 后 的 值 , 如 果 x 和 y 是 相 关 的 , 那 么 一 定 f ( x ) = f ( y ) . 考 虑 每 秒 钟 f ( x ) 会 如 何 变 换 : 发 现 当 f ( x ) 值 的 数 量 为 偶 数 个 的 时 候 , x 的 f ( x ) 会 变 成 1 ( 因 为 相 乘 之 后 幂 次 变 成 偶 数 次 , 会 被 去 掉 ) . 当 f ( x ) 值 的 数 量 为 奇 数 个 的 时 候 , x 的 f ( x ) 不 会 变 ( 因 为 偶 数 次 的 会 变 成 0 , 只 剩 下 一 个 ) . 变 一 次 之 后 只 剩 下 1 和 某 些 孤 立 的 f ( x ) , 之 后 不 会 再 变 了 . 因 此 只 需 要 计 算 出 t = 0 和 t = 1 时 候 的 f ( x ) 即 可 , 统 计 答 案 就 是 对 按 f ( x ) 计 数 . \frac {lcm(x,y)}{gcd(x,y)}=\frac{xy}{gcd(x,y)^2}\\ \frac{xy}{gcd(x,y)^2}=\frac{x}{gcd(x,y)}\frac{y}{gcd(x,y)}\\ 要使得上式结果是完全平方数,需要x和y去掉gcd部分后相乘为完全平方数.\\ 发现x个y各自的偶数次幂质因子也可以去掉,不影响相乘结果,\\ 设f(x)=x去掉偶数次幂质因子之后的值,\\ 如果x和y是相关的,那么一定f(x)=f(y).\\ 考虑每秒钟f(x)会如何变换:\\ 发现当f(x)值的数量为偶数个的时候,\\ x的f(x)会变成1(因为相乘之后幂次变成偶数次,会被去掉).\\ 当f(x)值的数量为奇数个的时候,\\ x的f(x)不会变(因为偶数次的会变成0,只剩下一个).\\ 变一次之后只剩下1和某些孤立的f(x),之后不会再变了.\\ 因此只需要计算出t=0和t=1时候的f(x)即可,\\ 统计答案就是对按f(x)计数. gcd(x,y)lcm(x,y)=gcd(x,y)2xygcd(x,y)2xy=gcd(x,y)xgcd(x,y)y要使得上式结果是完全平方数,需要x和y去掉gcd部分后相乘为完全平方数.发现x个y各自的偶数次幂质因子也可以去掉,不影响相乘结果,设f(x)=x去掉偶数次幂质因子之后的值,如果x和y是相关的,那么一定f(x)=f(y).考虑每秒钟f(x)会如何变换:发现当f(x)值的数量为偶数个的时候,x的f(x)会变成1(因为相乘之后幂次变成偶数次,会被去掉).当f(x)值的数量为奇数个的时候,x的f(x)不会变(因为偶数次的会变成0,只剩下一个).变一次之后只剩下1和某些孤立的f(x),之后不会再变了.因此只需要计算出t=0和t=1时候的f(x)即可,统计答案就是对按f(x)计数.
code:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxm=1e6+5;
int np[maxm];
int prime[maxm],cnt;
int a[maxm];
int f[maxm];
int n,q;
void init(){
for(int i=2;i<maxm;i++){
if(!np[i]){
prime[cnt++]=i;
}
for(int j=0;j<cnt;j++){
if(prime[j]*i>=maxm)break;
np[prime[i]*j]=1;
if(i%prime[j]==0)break;
}
}
}
void solve(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)f[i]=1;
for(int i=1;i<=n;i++){
int x=a[i];
for(int j=0;j<cnt&&prime[j]*prime[j]<=x;j++){
if(x%prime[j]==0){
int cc=0;
while(x%prime[j]==0)x/=prime[j],cc^=1;
if(cc){
f[i]*=prime[j];
}
}
}
if(x!=1)f[i]*=x;
}
int ans0=0;
int ans1=0;
//计算t=0时的答案
map<int,int>num0;
for(int i=1;i<=n;i++){
num0[f[i]]++;
}
for(auto i:num0){
ans0=max(ans0,i.second);
}
//计算t=1时的答案
map<int,int>num1;
for(int i=1;i<=n;i++){
if(num0[f[i]]%2==0){
f[i]=1;
}
num1[f[i]]++;
}
for(auto i:num1){
ans1=max(ans1,i.second);
}
//
scanf("%d",&q);
while(q--){
ll w;scanf("%lld",&w);
if(w==0)printf("%d\n",ans0);
else printf("%d\n",ans1);
}
}
signed main(){
init();
int T;cin>>T;
while(T--){
solve();
}
return 0;
}