CF1771C 质数分解+思维技巧题 *1600 (普及+/提高)

Problem - 1771C - Codeforces

有 T 组数据,每组数据给出 n 和长度为 n的数列 a[i],判断有没有两个数不互质,如果有输出 "YES",没有输出 "NO"

n≤2e5 1≤a[i]≤1e9

难度:*1600 (普及+/提高)

 

 

我们现设MAX=1e9

看到这种题目一定先要看a的数据范围,因为一定跟质数有关,还有与 √MAX 有关

那么a[i]是有两种可能 合数,质数

接下来是常见套路 我们先 筛选出 2~√MAX 之间的质数,大约是 3000 多个

对于a[i],我们先用2~√MAX 之间的质数除 ,如果删后的  a[i] 不为1,那么除后的 a[i] 它一定是个大于 √MAX的质数,∈(√MAX,MAX)

显然对于此时的大质数,我们用mp来存储。

对于2~√MAX 之间的质数 我们完全由能力定义数组来判断它出现的次数,这就用 bool vis1[N]来表示

对于√MAX~MAX 之间的质数,我们用mp来存这种大指数,这就用 map<int,bool> vis2[N]来表示

那么此题就做好了

复杂度为O( 筛选质数+N*prime.size() ) 6e8感觉挺极限的,跑起来900ms

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   //vector函数
#define popb pop_back  //vector函数
#define fi first
#define se second
const int N=4e5;
//const int M=;
//const int inf=0x3f3f3f3f;     //一般为int赋最大值,不用于memset中
//const ll INF=0x3ffffffffffff; //一般为ll赋最大值,不用于memset中
int T,n,a[N];
bool vis[N],vis1[N];
vector<int> prime,v;
map<int,bool> vis2;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
void getprime()
{
    int M=(int)sqrt(1e9);
//    printf("%d\n",M);
    for(int i=2;i<=M;i++)
    {
        if(vis[i]) continue;
        prime.pb(i);
        for(int j=i;i*j<=M;j++) vis[i*j]=1;
    }
    printf("%d",prime.size());
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    T=read();
    getprime();
    while(T--)
    {
        n=read();
        bool ok=0;
        for(int i=1;i<=n;i++) 
        {
            a[i]=read();
            for(int x:prime)
            {
                if(x>a[i]) break;
                if(a[i]%x==0) 
                {
                    if(vis1[x]) ok=1;
                    if(!vis[x]) vis1[x]=1,v.pb(x);
                    while(a[i]%x==0) a[i]/=x;
                }   
            }
            if(a[i]!=1)
            {
                if(vis2[a[i]]) ok=1;
                vis2[a[i]]=1;
            }
        }
        if(ok) puts("YES");
        else puts("NO");
        vis2.clear();
        for(int x:v) vis1[x]=0;
        v.clear();
    }
    return 0;
}

 

posted @ 2023-01-14 00:15  QAQ啥也不会  阅读(29)  评论(0编辑  收藏  举报