题目连接:http://acm.hit.edu.cn/hoj/problem/view?id=1356
本题我曾想以[1,500000]内的质因子为基础来判定整个int范围的质数,但是超时。
无奈用Miller Rabin算法吧。
根据 :费尔马小定理,如果 n 为素数,那么对于小于n的数a有a^(n-1) = 1(mod n)
那么我们可以随机生成一个a(a<n),如果满足a^(n-1) = 1(mod n),那么n就有可能是质数。随机生成三次,即验证三次,那么这个概率就非常大。
关于a^b%n,用快速幂来解。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> using namespace std; long long mul(long long a,long long b) { return a * b; } long long power(long long a,long long b,int n) { //快速幂取模a^b%n long long b_temp = b; long long result = 1; while(b_temp) { if(b_temp&1) { result = mul(result,a)%n; } a = mul(a,a)%n; b_temp = b_temp>>1; } return result; } bool Miller_Rabbin(long long n) { //费尔马小定理,如果 n 为素数,那么对于小于n的数a有a^(n-1) = 1(mod n) long long a = rand()%(n-1)+1;//随机生成一个小于n的数 //a^(n-1) = 1(mod n) if(power(a,n-1,n)!=1) { return false; } return true; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif long long n; while(scanf("%lld",&n)!=EOF) { int flag = 1;//1表示素数 int times = 3;//times为每个数进行测试的次数 if(n<=1) { flag = 0; } else if(n==2||n==3) { flag = 1; } else { while(times--&&flag) { if(!Miller_Rabbin(n)) { flag = 0; } } } if(!flag) { printf("NO\n"); } else { printf("YES\n"); } } return 0; }
作者:niuox 发表于2013-2-18 23:33:17 原文链接
阅读:81 评论:0 查看评论