• 杂题1 素数


    1、埃拉托斯特尼筛法

    const int MAXN = 1000000; 
    void Prime()  
    {  
        for (int i=0; i<MAXN; i++) prime[i]=1;  //先把每个数都定义为合数
        prime[0]=prime[1]=0;  
        for (int i=2; i<MAXN; i++)  
        {  
            if (!prime[i]) continue;  //如果为0就跳过,说明是素数 
            for (int j=i*2; j<MAXN; j+=i) prime[j] = 0;  //将i的倍数标记为合数
            //筛去2的倍数4、6、8,筛去3的倍数... 
        }  
    } 

    2、欧拉筛

    //O(n)的筛法,每个合数只被它的最小质因子筛一次
    //每一次的外循环筛出i和找到的质数
    int  maxn;
    int prime[120000];//prime[0]记录当前为止找到的素数的个数,1~maxn存找到的素数
    int visit[120000];//其值为0时是素数,1~maxn用来打表 
    void Prime()
    {
        memset(visit,0,sizeof(visit));
        memset(prime, 0,sizeof(prime));
        for (int i = 2; i <= maxn; i++)
        {
    //        cout<<" i = "<<i<<endl;
            if (!visit[i])
            {
                prime[++prime[0]] = i;//记录素数的个数,同时存找到的素数
            }
            for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++)//遍历每一个已找到的素数并且素数的倍数小于等于maxn 
            {
    //            cout<<"           j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;
                visit[i*prime[j]] = 1;//这个素数的倍数是合数
                if (i % prime[j] == 0)//因为每个数只被它的最小质因子筛一次,在此之后的质数不用筛,以后会筛
                {
                    break;
                }
            }
        }
    }

    3、Miller-Rabin判断法

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll qpow(ll x,ll y,ll p)//x^y mod p
    {
        ll ans=1,m=x;
        while(y)
        {
            if(y&1)ans*=m;
            ans%=p;
            m*=m;
            m%=p;
            y>>=1;
        }
        return ans;
    }
    bool check(ll x,ll y,ll p)
    {
        ll q=qpow(x,y,p);
        if(q!=1&&q!=p-1)return 0;
        if(q==p-1)return 1;
        if(q==1&&(y&1))return 1;
        return check(x,y>>1,p);
    }
    bool mil(ll x)
    {
        if(x<=1)return 0;
        if(x==2||x==7||x==61||(check(2,x-1,x)&&check(7,x-1,x)&&check(61,x-1,x)))/*底数RP++*/return true;
        return 0;
    }
    int main()
    {
        int n,m;
        ll k;
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>k;
            if(mil(k))cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
        return 0;
    }

    由于暂时看不懂.....先搁在这

    可以参考下https://www.cnblogs.com/bytebull/p/11179316.html

    luoguP3912 素数个数

    题目描述

    1,2,⋯ ,N1,2,cdots,N1,2,,N 中素数的个数。

    输入格式

    一行一个整数 NNN。

    输出格式

    一行一个整数,表示素数的个数。

    输入输出样例

    输入 #1
    10
    输出 #1
    4

    说明/提示

    对于 40% 的数据,1N10^6。

    对于 80% 的数据,1N10^7。

    对于 100% 的数据,1N10^8。

    解题思路

    类似埃拉托斯特尼筛法,稍微做点改进

    #include<bits/stdc++.h>
    using namespace std;
    bool a[100000000];//其值为0是素数 
    int main() {
        int n,i,j,s=0;
        cin>>n;
        memset(a,0,sizeof(a));
        s=n-1;//去1 
        for(i=2; i*i<=n; i++) {
            if(a[i]==0)
                for(j=i*2; j<=n; j+=i) 
                    if(a[j]==0) {//j必为合数,则去合数 
                        cout<<" i = "<<i<<" j = "<<j<<endl; 
                        a[j]=1;
                        s--;
                    }
        }
        cout<<s;
      return 0; }

    P1835 素数密度

    题目描述

    给定区间[L,R](L≤R≤2147483647,R-L≤1000000),请计算区间中素数的个数。

    输入格式

    两个数L和R。

    输出格式

    一行,区间中素数的个数。

    输入输出样例

    输入 #1
    2 11
    输出 #1
    5

    解题思路

    看数据范围用简单筛法明显不行,不过呢L~R的范围很小

    只要筛掉√2147483647内所有质数,然后用这其中的质数筛[l,r]内的数

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn = 1000000;
    int l , r;
    
    int prime[maxn] , cnt=0 , tot=0;//cnt为质因子个数,tot为答案
    bool vis[maxn];
    bool ans[maxn];
    
    void Euler() {
        for(int i = 2 ; i <= 50000 ; ++ i) {
            if(!vis[i]) {
                prime[++cnt] = i;
                for(int j = i + i ; j <= 50000 ; j += i) {
                    vis[j] = 1;
                }
            }
        }
    }
    int _max(int a , int b) {
        return a > b ?  a : b;
    }
    
    signed main () {//因为前面 #define int long long了,这里int = signed int = signed
        Euler();
        cin>>l>>r;
        for(int i = 1 ; i <= cnt ;  i++) {
            for(int j = _max( 2 , (l - 1)/prime[i] + 1) * prime[i] ; j <= r ; j += prime[i]) 
                if(j - l >= 0) ans[j - l]=1;//等于1为合数
            }
            for(int i = 0 ; i <= r - l ;  i++)
                if(!ans[i]) tot ++;
            cout<<tot;
            return 0;
        }

    P3383 【模板】线性筛素数

    题目背景

    本题已更新,从判断素数改为了查询第 kkk 小的素数
    提示:如果你使用 cin 来读入,建议使用 std::ios::sync_with_stdio(0) 来加速。

    题目描述

    如题,给定一个范围 n,有 q 个询问,每次输出第 k 小的素数。

    输入格式

    第一行包含两个正整数 n,q分别表示查询的范围和查询的个数。

    接下来 q行每行一个正整数 k,表示查询第 k小的素数。

    输出格式

    输出 q 行,每行一个正整数表示答案。

    输入输出样例

    输入 #1
    100 5
    1
    2
    3
    4
    5
    输出 #1
    2
    3
    5
    7
    11

    说明/提示

    【数据范围】
    对于 100% 的数据,n=108n = 10^8n=108,1≤q≤10^6,保证查询的素数不大于 n

    Data by NaCly_Fish.

    解题思路

     用欧拉筛可以,但要注意数组的大小

    #include<bits/stdc++.h>
    using namespace std;
    int prime[6000010];
    bool visit[100000010];//1为素数 
    void getPrime(int  maxn)
    {
        memset(visit,1,sizeof(visit));
        memset(prime,0,sizeof(prime));
        visit[1]=0;
        for (int i = 2; i <= maxn; i++)
        {
    
            if (visit[i])
            {
                prime[++prime[0]] = i;
            }
            for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++)
            {
    
                visit[i*prime[j]] = 0;
                if (i % prime[j] == 0)
                {
                    break;
                }
            }
        }
    }
    int main(){
        int n,k,maxn;
        cin>>maxn>>n;
        getPrime(maxn);
        for(int i=1; i<=n; i++){
            cin>>k;
            cout<<prime[k]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    css的书写位置+元素分类
    选择器
    我的js运动库新
    js的相关距离
    关于小乌龟的使用
    linux 基础
    linux shell快捷操作【超级实用】
    算法面试常见问题【转】
    http://www.cnblogs.com/zhangchaoyang/archive/2012/08/28/2660929.html
    cocos2dx + vs安装使用
  • 原文地址:https://www.cnblogs.com/rakanXayan/p/13406408.html
Copyright © 2020-2023  润新知