Problem - C - Codeforces
胡萨姆有n名学员。他给第i个学员分配了一个号码。
如果存在一个整数x (x≥2),使得x能整除ai, x能整除aj,则第i个和第j个(i≠j)练习者被称为成功练习者。
胡萨姆想知道是否有一对成功的学员。
胡萨姆现在很累了,所以他向你求助!
输入
输入由多个测试用例组成。第一行包含一个整数t(1≤t≤105),测试用例的数量。下面是测试用例的描述。
每个测试用例的第一行包含一个整数n(2≤n≤105)。
每个测试用例的第二行包含n个整数,每个受训者的数量a1,a2,…,an(1≤ai≤109)。
它保证所有测试用例的n和不超过105。
输出
打印答案-“是”(不加引号)如果有一对成功的学员,否则打印“否”。在任何情况下你都可以打印每封信。
例子
inputCopy
2
3.
32 48 7
3.
14 5 9
outputCopy
是的
没有
请注意
在第一个例子中,第一个练习生和第二个练习生组成了一对成功的搭档:
A1 =32,a2=48,可以选x=4。
题解:
根据唯一的分解定理任何整数都可以分级为一些不同质数幂次方的乘积,我们再先于处理sqrt(1e9)范围内的所有质数,然后分解给我们的n个数,在没找到之前一直分解,标记质因数,找到后直接跳过即可
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<cstring>
#include<cmath>
using namespace std;
#define int long long
int st[1000060];
int p[1000060];
int cnt = 0;
void solve()
{
int n;
cin >> n;
int f = 0;
map<int,int> vis;
for(int i = 1;i <= n;i++)
{
int x;
cin >> x;
if(f)
continue;
for(int j = 1;p[j]*p[j] <= x;j++)
{
if(x%p[j] == 0)
{
if(vis[p[j]])
{
f = 1;
break;
}
vis[p[j]] = 1;
while(x%p[j] == 0)
{
x /= p[j];
}
}
}
if(x > 1)
{
if(vis[x])
f = 1;
vis[x] = 1;
}
}
if(f)
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
st[1]=1;
for(int i=2;i<=40000;i++){
if(st[i]==0)
p[++cnt]=i;
for(int j=1;j<=cnt&&i*p[j]<=40000;j++){
st[i*p[j]]=1;
if(i%p[j]==0)
break;
}
}
while(t--)
{
solve();
}
}
//WBBW
//B