素数问题

除了2以外,素数都是奇数,这是关键

1.快速查找素数(范围大所以用数组)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 1000000
using namespace std;
bool hash[N];
int main()
{
    int i,j=0;

(最快)0.3s

for(j=4;j<N;j+=2)//把2的倍数排除,但2是素数,所以从4开始   

    hash[j]=1;    

for(i=3;i<1000;i+=2)

if(!hash[i])

for(j=i*i;j<N;j+=i)

    hash[j]=1;

或者(次之)0.6s
    for(j=4;j<N;j+=2)//把2的倍数排除,但2是素数,所以从4开始
      hash[j]=1;
    for(i=3;i<1000;i+=2)
      if(!hash[i])
       for(j=i+i;j<N;j+=i)//3,5,7,....的2,3,4,5,6,7,,,,,,倍
         hash[j]=1;

  可以写成(差不多)

for(i=2;i<1000;i++)
    if(!hash[i])

   for(j=2;j*i<N;j++)

           hash[i*j]=1;   
    for(j=0,i=2;i<N;i++)
      if(!hash[i])
       j++;
    printf("%d\n",j);
    return 0;
}

 2.输出n以内的素数(个数明显能输出)

#include<iostream>

#include<cmath>

#include<cstdio>

#include<cmath>

using namespace std;

const int M1=2000100,M2=1000000;

bool NotPrime[M1]={1,1,0};

int Prime[M2];

int PrimeNum=0;

int main()

{

int n;

for(int i=2;i<=1415;i++)

if(!NotPrime[i])

{

Prime[PrimeNum++]=i;

for(int j=i*i;j<=2000000;j+=i)

{

NotPrime[j]=1;

}

}

for( i=Prime[PrimeNum-1]+1;i<=2000000;i++)

if(!NotPrime[i]) Prime[PrimeNum++]=i;

int sum=0;

while(scanf("%d",&n)&&n)

{

for(i=0;Prime[i]<=n && Prime[i];i++)

{  

sum++; printf("%d ",Prime[i]);

puts("");

}

cout<<sum<<endl;

sum=0;

}

return 0;

}    

 

2.求素因子个数和素因子之和(选自Simith Numbers)

void prime()//,判断sqrt(x)以内的素数,但可能有一个超过sqrt(x)的素数,下面有函数判断

{

LL i,j;

//memset(a,1,MAXN+1);//曾今用这个判断素数,超时。

a[1]=1;

for(i=2,j=2;i*j<=MAXN;j++)

a[i*j]=1;

for(i=3;i<100;i+=2)

{

if(!a[i])

{

for(j=2;i*j<=MAXN;j++)

a[i*j]=1;

}

}

}

bool myth(LL x)//判断超过sqrt(x)这个素数(这种判断方法一般是为了判断一个素数)

{

LL i;

if(x==2)return true;

if(x%2==0||x==1)return false;

for(i=3;i*i<=x;i+=2)

if(x%i==0)return false;

    return true;//判断一个素数快速方法

}

 

int main()

{

LL x,sum,j,i,temp;

prime();

j=0;

for(i=2;i<=MAXN;i++)打表,将素因子保存。为了循环时减少时间。

if(!a[i])

    save[j++]=i;

while(scanf("%d",&x)&&x)

{

while(++x)

{

sum=0;

temp=x;

if(myth(temp))

continue;

i=0;

while(temp!=1)

{

while(temp%save[i]==0)

{

   sum+=Smith(save[i]);

    temp=temp/save[i];//将其循环个数保存就可以判断有几个素因子

}

i++;

if(myth(temp))//大于10000的素数最多出现一次

{

     sum+=Smith(temp);

break;

}

(A1B1+A2B2+  ... +AHBH)mod M

 求A1B11mod/M......(A,B,M)都很大,这个管用

int powmod (int a,int b,int n)
{
if(b==0)return 1;
int k=1;
while(b>=1)
{
  if(b%2!=0)k=a*k%n;
  a=((a%n)*(a%n))%n;//算a^2 mod n因为计算机可以保存中间结果,减少计算时间。
  b/=2;
}
return k;
}

//注意(a*b)%m=((a%m)*(b%m))/m

 

 

posted @ 2012-07-28 11:01  myth_HG  阅读(351)  评论(0编辑  收藏  举报