首页 > 其他 > 详细

素数 专题

时间:2015-09-07 00:29:45      阅读:283      评论:0      收藏:0      [点我收藏+]

素数性质总结:

  1. 小于x的素数个数(随着x逐渐增大),与x/lnx近似;
  2. 素数测试方法,诶拉托色尼筛法:如果n是一个合数,那么n一定有一个不超过sqrt(n)的素因子;6N±1法:对于任何一个自然数,都可以表示为如下形式之一:6N,6N+1,6N+2,6N+3,6N+4,6N+5(N=0,1,2,3...)显然,当N>=1时,只有形如6N+1,6N+5的自然数有可能是素数(代码后面贴上)
  3. n!的素因子分解中的素数p的幂为  n/p+n/p2+n/p3+......
  4. 梅森素数:如果m是一个正整数,且2m-1是一个素数,则m必是素数(通过2m-1来判断m是否为素数,很重要的运用);如果m是一个正整数,且m是一个素数,则Mm=2m-1称作第m个梅森数,如果p是一个素数,且Mp=2p-1也是素数,则Mp就称为梅森素数。判断方法有lucas-lehmer判定法【设p是素数,第p个梅森素数为Mp=2p-1,r1=4,对于k>=2,利用rk=r2k-1-2(modMp),0<=rk<Mp,可以得到rk序列,则有Mp为素数,当且仅当rp-1=0(modMp).】和miller素数测试法

miller素数测试法:

一.费马小定理

如果n是素数,且gcd(a,n)==1,那么a(n-1)==1(mod n);

费马小定理只是个必要条件,符合费马小定理而非素数的数叫做Carmichael.

前3个Carmichael数是561,1105,1729。

Carmichael数是非常少的。

在1~100000000范围内的整数中,只有255个Carmichael数。

为此又有二次探测定理,以确保该数为素数:

二.二次探测定理

二次探测定理:如果p是一个素数,0<x<p,则方程x2≡1(mod p)的解为x=1,p-1

大神orz

题目集合:

hdu 2138 How many prime numbers  http://acm.hdu.edu.cn/showproblem.php?pid=2138 虽然这题比较水,可以直接判断sqrt(n)以内的数是否可以被n整除来判断n是否为素数。但如果用miller素数测试法来做的话还是挺好的一个训练题。不过坑点也蛮多的,我用g++编译相同的代码就tle,而c++就可以刚好过,具体的代码中有标识

/**************************************************************
    Problem:hdu 2138
    User: youmi
    Language: C++
    Result: Accepted
    Time:764MS
    Memory:1732K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <ctime>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
int N;
//下面分别是判15次和判10次的时间差别
const int Times=15;//998MS    1728K
//const int Times=10 764MS  1732K
ll mod_mul(ll a,ll b,ll mod)
{
    ll res=0;
    a%=mod;
    while(b)
    {
        if(b&1)
            res=(res+a)%mod;
        b>>=1;
        a=(a<<1)%mod;
    }
    return res;
}
ll mod_exp(ll a,ll b,ll mod)
{
    ll res=1;
    a%=mod;
    while(b)
    {
        if(b&1)
            res=mod_mul(res,a,mod);
        b>>=1;
        a=mod_mul(a,a,mod);
    }
    return res;
}
bool miller_rabin(ll n)
{
    if(n==2||n==3||n==5||n==7||n==11)
        return true;
    if(n==1||n%2==0||n%3==0||n%5==0||n%7==0||n%11==0)
        return false;
    int tot=0;
    ll u=n-1; //要求x^u % n
    while(!(u&1))//如果u为偶数则u右移,用tot记录移位数,然后可以利用x^2==1来进行tot次二次判定,
    {
        tot++;u>>=1;
    }
    rep1(i,Times)//进行Times次测试
    {
        ll x=rand()%(n-2)+2;//在[2, n)中取随机数
        if(x==n)
            continue;
        x=mod_exp(x,u,n);//先计算(x^u) % n
        ll pre=x;
        rep0(j,tot)//把移位减掉的量补上,并在这地方加上二次探测
        {
            x=mod_mul(x,x,n);
            if(x==1&&pre!=1&&pre!=n-1)//二次探测定理,这里如果x = 1则pre 必须等于 1,或则 n-1否则可以判断不是素数
                return false;
            pre=x;
        }
        if(x!=1)//费马小定理
            return false;
    }
    return true;
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(~sc(N))
    {
        ll a;
        int cnt=0;
        srand(time(NULL));//随机数种子生成器
        while(N--)
        {
            sclld(a);
            if(miller_rabin(a))
                cnt++;
        }
        pt(cnt);
    }
    return 0;
}

 

更新中

素数 专题

原文:http://www.cnblogs.com/youmi/p/4787734.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!