素数问题
除了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