首页 > 其他分享 >CF1771C 质数分解+思维技巧题 *1600 (普及+/提高)

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

时间:2023-01-14 00:34:37浏览次数:69  
标签:vis2 ch CF1771C int 1600 质数 MAX define

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;
}

 

标签:vis2,ch,CF1771C,int,1600,质数,MAX,define
From: https://www.cnblogs.com/Willette/p/17051034.html

相关文章

  • D. Friendly Spiders(bfs最短路径、质数虚点建图)
    题意:给一个长度为n的数组a,数组中两两不互质的数可以建一条边,即$gcd(a[i],a[j])≠1$,i,j之间存在伊奥无向边问s到t的最短路径是多长,并输出题解根据唯一分解......
  • 补题:回文质数
    本质上这题还是有关筛素数,但是增多了一些细节,还是值得注意和思考一下的题目大意为在一个有限范围内求出[a,b]内即是回文数又是质数的数并打出一开始是也是想先把质数筛......
  • 质数筛法
    质数筛法引入原题链接:P3912素数个数-洛谷求\(1\simn\)有多少个质数朴素求法,时间复杂度\(O(n\sqrt{n})\)importjava.util.Scanner;publicclassMain{......
  • P1217 [USACO1.5]回文质数 Prime Palindromes
    题目题目描述因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以151是回文质数。写一个程序来找出范围[a,b](5<=a<b<=100,000,000)(一亿)间的......
  • Prime number 质数相关
    什么是质数?在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数,比如:2,3,5,7,11...什么是合数?比1大但不是素数的数称为合数。1和0既非素数也非合数。合数是......
  • 质数判断——暴力方法、埃氏筛与线性筛
    质数判断  问题背景为:我们希望判断前n个数是否为质数,即得到isPrime[n+1](此处沿用java语言定义)数组。暴力方法  传统意义上的对质数的判断方法,是依据质数的定义—......
  • P1600 [NOIP2016 提高组] 天天爱跑步
    //题目大意:有一棵树,在每个节点上会在Pi时刻出现一个观察员,在该时刻观察员如果观察到路过的运动员,那么该观察员的分数加1;//现在给定m条路径的起点与终点,每个运......
  • 质数与约数
    质数与约数质数质数和合数的概念只针对于大于1的整数成立。质数:在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数,或者素数。质数的判定试除法boolis_prim......
  • 08 回文质数 -Linux环境下的编译执行
    打开终端(terminal)输入cdm//打开m文件输入touchmain.cpp//新建main.cpp文件输入vimmain.cpp//使用vim来编写代码编写完毕后输入:wq//保存并退出输入g++main......
  • 判别质数
    某一天新发现的判断一个正整数是否是质数的方法,思路大概如下所示: #include<stdio.h> #include<stdlib.h> intmain(){  intn;  intflag=1;  pri......