http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1122
Miller_Rabin测试原理:
http://www.xuebuyuan.com/552593.html
题目描述
从键盘上输入任意一个整数,然后判断该数是否为素数。
如果是素数则输出"This is a prime."
否则输出“This is not a prime.”
输入
输入任意一个整数n。
输出
判断n是否为素数,并输出判断结果:
如果n是素数则输出"This is a prime."
否则输出“This is not a prime.”
示例输入
3
示例输出
This is a prime.
#include #include long long mod_pro(long long x,long long y,long long n)//求(x*y)%n
{
long long ret=0,tmp=x%n;
while(y)
{
if(y&0x1)
if((ret+=tmp)>n)
ret-=n;
if((tmp<<=1)>n)
tmp-=n;
y>>=1;
}
return ret;
}
long long mod(long long a,long long b,long long c)//快速幂,求(a^b) % c
{
long long ret=1;
while(b)
{
if(b&0x1)
ret=mod_pro(ret,a,c);
a=mod_pro(a,a,c);
b>>=1;
}
return ret;
}
long long ran()
{
long long ret=rand();
return ret*rand();
}
/*Fermat小定理: a^(n-1) =1(mod n)*/
/*二次探测定理: x^2=1(mod n),n is prime => x=1 or x=n-1*/
/*Miller_Rabin测试(正向迭代法): a^(u*2^t)=1(mod n),n is prime => a^u=1(mod n) or Exist i,a^(u*2^i)=(n-1)(mod n)*/
int Miller_Rabin(long long n,int time)
{
long long k,m,a,i;
if(n<2)//0,1不是素数
return 0;
if(n==2)//2是素数
return 1;
if(!(n&0x1))//偶数不是素数
return 0;
k=0;
for(m=n-1;!(m&1);m>>=1,k++);/*m是偶数,就不断的提取2,直到m变成奇数(u)*/
while(time--)
{
a=mod(ran()%(n-2)+2,m,n);//a=随机数^u % n,随机数:2~n-1。rand()%x的结果最大为x-1,最小为0
if(a!=1)
{
for(i=0;i=k)
return 0;
}
}
return 1;
}
int main()
{
long long i;
scanf("%lld",&i);
if(Miller_Rabin(i,1))
printf("This is a prime.\n");
else
printf("This is not a prime.\n");
return 0;
}
/**************************************
Problem id: SDUT OJ 1122
User name: 2333
Result: Accepted
Take Memory: 284K
Take Time: 0MS
Submit Time: 2016-07-11 16:09:48
**************************************/