开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
C - Hossam and Trainees
题意:给出一个数组,如果有a[i],a[j],i!=j,且存在有一个数x>=2,a[i]%x==0,a[j]%x==0,则表示这个数组符合条件,现在给出多组样例问给出的数组是否满足条件
思路:a[i]的范围是1e9,这样可以筛出根号(1e9)的质数然后直接枚举check就可以,原以为这样会超时,但并不会,根号1e9约等于31663,去个整也就是32000,然后有一个结论是前N个数里面的质数的个数为N/ln(N),这样一算也就是3400多个数,然后还有外层n的范围1e5也就是3e8左右,这还是最坏的情况,题目给了3s应该是够用了,这个题目没有仔细地去分析,漏掉了一个关键的信息(其实也想到了但没往下继续想):枚举出根号(1e9)的质数后,如果一个数m(在1e9范围以内)不能被这些数整除,那么这个数m就是一个大于根号(1e9)的质数,不知道为啥当时竟然不知道如何处理或者是判断这种情况了,其实既然是质数那么直接记录就可以了,另外在实现的时候注意一些细节就可以了
Codeforces Round #837 (Div. 2) C(因数分解) D(树上DP) - 知乎 (zhihu.com)
#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int pri[N],cnt;
bool isp[N];
void is_pri(int n)
{
memset(isp,1,sizeof(isp));
cnt=0;
isp[0]=isp[1]=0;
for(int i=2;i<=n;i++)
{
if(isp[i]) pri[++cnt]=i;
for(int j=1;j<=cnt&&i*pri[j]<=n;j++)
{
isp[i*pri[j]]=0;
if(i%pri[j]==0) break;
}
}
}
int t,n,a[N];
map<int,int>mp;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
is_pri(32000);
cout<<cnt<<endl;
cin>>t;
while(t--)
{
cin>>n;
int flag=0;
mp.clear();
for(int i=1;i<=n;i++)
{
cin>>a[i];
for(int j=1;j<=cnt&&pri[j]*pri[j]<=a[i];j++)
{
if(a[i]%pri[j]==0)
{
mp[pri[j]]++;
if(mp[pri[j]]>=2) flag=1;
while(a[i]%pri[j]==0) a[i]/=pri[j];
}
}
if(a[i]>1) mp[a[i]]++;
if(mp[a[i]]>=2) flag=1;
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}