51nod 1106质数检测(小素数)

来源:互联网 发布:mysql外键怎么设置 编辑:程序博客网 时间:2024/06/08 14:21

1106 质数检测
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
 收藏
 关注
给出N个正整数,检测每个数是否为质数。如果是,输出"Yes",否则输出"No"。
Input
第1行:一个数N,表示正整数的数量。(1 <= N <= 1000)第2 - N + 1行:每行1个数(2 <= S[i] <= 10^9)
Output
输出共N行,每行为 Yes 或 No。
Input示例
523456
Output示例
YesYesNoYesNo

题解:

MillierRabin素数检测算法与二次探测定理。

引入x*y mod n是防止中间过程x*y大于n。x*y mod n的过程实际上就是当作二进制乘法。


代码:

#include <stdio.h>#include <stdlib.h>long long mod_pro(long long x, long long y, long long n){ //求(x*y)%nlong 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) % clong 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();}int is_prime(long long n, int t) {//判断大整数n是否为素数,使用二次探测定理long long k = 0, m, a, i;if (n<2) //0,1不是素数return 0;if (n == 2)return 1;if (!(n & 0x1)) //偶数不是素数return 0;for (m = n - 1; !(m & 1); m >>= 1, k++) {//n-1 = m * 2^k(m为奇数, k>=1);}while (t--){a = mod(ran() % (n - 2) + 2, m, n); //rand^m % nif (a != 1) //符合等于1的情形,直接是素数{   //反复平方,原路返回等于n-1的情形,一定会小于等于k次,否则不是素数for (i = 1; i <= k; i++){if (a == n - 1) break;a = mod_pro(a, a, n); }if (i >= k+1)return 0;}}return 1;}int main(){int t;long long n;scanf("%d", &t);while (t--){scanf("%lld", &n);if (is_prime(n, 1))printf("Yes\n");elseprintf("No\n");}return 0;}


原创粉丝点击