大素数测试和分解质因数

Prime Test http://poj.org/problem?id=1811

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 typedef __int64 LL;
  5 LL mulmod(LL a,LL b,LL c) { //ret=(a*b)%c
  6     LL ret=0;
  7     for(; b; a=(a<<1)%c,b>>=1) {
  8         if(b&1) {
  9             ret=(ret+a)%c;
 10         }
 11     }
 12     return ret;
 13 }
 14 LL powmod(LL a,LL b,LL c) { //ret=(a^b)%mod
 15     LL ret=1%c;
 16     for(; b; a=mulmod(a,a,c),b>>=1) {
 17         if(b&1) {
 18             ret=mulmod(ret,a,c);
 19         }
 20     }
 21     return ret;
 22 }
 23 bool suspect(LL a,int s,LL d,LL n) {
 24     LL x=powmod(a,d,n);
 25     if(x==1) return true;
 26     while(s--) {
 27         if(x==n-1) return true;
 28         x=mulmod(x,x,n);
 29     }
 30     return false;
 31 }
 32 const int test[]= {2,3,5,7,11,13,17,19,23,-1}; // for n < 10^16
 33 bool isprime(LL n) { //Miller-Rabin 大素数测试
 34     if(n<=1||(n>2&&(!(n&1)))) return false;
 35     LL d=n-1;
 36     int s=0;
 37     while(!(d&1)) {
 38         s++;
 39         d>>=1;
 40     }
 41     for(int i=0; test[i]<n&&~test[i]; i++) {
 42         if(!suspect(test[i],s,d,n)) return false;
 43     }
 44     return true;
 45 }
 46 LL gcd(LL a,LL b){//最大公约数
 47     return b?gcd(b,a%b):a;
 48 }
 49 LL pollard_rho(LL n,LL c){//Pollard-Rho 找到n的一个约数
 50     LL d,x=rand()%n,y=x;
 51     for(LL i=1,k=2;;i++){
 52         x=(mulmod(x,x,n)+c)%n;
 53         d=gcd(y-x,n);
 54         if(d>1&&d<n) return d;
 55         if(x==y) return n;
 56         if(i==k){
 57             y=x;
 58             k<<=1;
 59         }
 60     }
 61     return 0;
 62 }
 63 LL factor[128];//质因素分解结果(刚返回时时无序的)
 64 int flen;//质因素的个数,编号0~tol-1
 65 void findfac(LL n,int k) {
 66     if(n==1) return;
 67     if(isprime(n)) {
 68         factor[flen++]=n;
 69         return ;
 70     }
 71     LL p=n;
 72     int c=k;
 73     while(p>=n) {
 74         p=pollard_rho(p,c--);
 75     }
 76     findfac(p,k);
 77     findfac(n/p,k);
 78 }
 79 int main() {
 80     int t;
 81     LL n;
 82     while(~scanf("%d",&t)) {
 83         while(t--) {
 84             scanf("%I64d",&n);
 85             if(isprime(n)) {
 86                 puts("Prime");
 87                 continue;
 88             } else {
 89                 flen=0;
 90                 findfac(n,107);
 91                 LL ans=factor[0];
 92                 for(int i=1; i<flen; i++) {
 93                     ans=min(ans,factor[i]);
 94                 }
 95                 printf("%I64d\n",ans);
 96             }
 97         }
 98     }
 99     return 0;
100 }

How many prime numbers http://acm.hdu.edu.cn/showproblem.php?pid=2138

 1 #include<cstdio>
 2 typedef __int64 LL;
 3 LL mulmod(LL a,LL b,LL c) { //ret=(a*b)%c
 4     LL ret=0;
 5     for(; b; a=(a<<1)%c,b>>=1) {
 6         if(b&1) {
 7             ret=(ret+a)%c;
 8         }
 9     }
10     return ret;
11 }
12 LL powmod(LL a,LL b,LL c) { //ret=(a^b)%mod
13     LL ret=1%c;
14     for(; b; a=mulmod(a,a,c),b>>=1) {
15         if(b&1) {
16             ret=mulmod(ret,a,c);
17         }
18     }
19     return ret;
20 }
21 bool suspect(LL a,int s,LL d,LL n) {
22     LL x=powmod(a,d,n);
23     if(x==1) return true;
24     while(s--) {
25         if(x==n-1) return true;
26         x=mulmod(x,x,n);
27     }
28     return false;
29 }
30 const int test[]= {2,3,5,7,11,13,17,19,23,-1}; // for n < 10^16
31 bool isprime(LL n) { //Miller-Rabin 大素数测试
32     if(n<=1||(n>2&&(!(n&1)))) return false;
33     LL d=n-1;
34     int s=0;
35     while(!(d&1)) {
36         s++;
37         d>>=1;
38     }
39     for(int i=0; test[i]<n&&~test[i]; i++) {
40         if(!suspect(test[i],s,d,n)) return false;
41     }
42     return true;
43 }
44 int main(){
45     int n,x;
46     while(~scanf("%d",&n)){
47         int ans=0;
48         while(n--){
49             scanf("%d",&x);
50             if(isprime(x)) ans++;
51         }
52         printf("%d\n",ans);
53     }
54     return 0;
55 }

end

大素数测试和分解质因数

时间: 2024-10-12 20:55:55

大素数测试和分解质因数的相关文章

Miller_Rabbin大素数测试

伪素数: 如果存在和n互素的正整数a满足a^(n-1)≡1(mod n),则n是基于a的伪素数. 是伪素数但不是素数的个数是非常非常少的,所以如果一个数是伪素数,那么他几乎是素数. Miller_Rabbin素数测试:随机选k个a进行a^(n-1)≡1(mod n)测试,如果都满足则判断n是素数. a^(n-1)%mod用快速幂计算.对于大数相乘(两个大于int的数相乘),中间结果可能溢出,所以需要用快速幂思想进行乘法取模. Miller_Rabbin的出错率为2^(-k). 1 //Mille

Miller-Rabin大素数测试模板

根据费马小定理: 对于素数n,a(0<a<n),a^(n-1)=1(mod n) 如果对于一个<n的正整数a,a^(n-1)!=1(mod n),则n必不是素数. 然后就可以随机生成  <n的数,如果都满足,那n就极有可能是素数. 看书上说,一次素数测试的成功率是 3/4,也就是失败率是1/4,那测m次是错误的概率为:(1/4)^m.可见m稍微大一点就基本不会出错. 但是还有一种数叫,卡迈克尔数. 卡迈克尔数: 一个合数n,对所有满足 gcd(b,n)=1的正整数b都有b^(n-1

Miller_Rabin大素数测试与Pollard_rho整数分解模版

#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; typedef __int64 LL; const int Times = 20; LL factor[100], l; LL gcd(LL a, LL b) { return b ? gcd(b, a%b):a; } LL add_mod(LL a, LL b,

数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the

数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)

数学渣渣愉快的玩了一把数论,来总结一下几种常用的算法入门,不过鶸也是刚刚入门, 所以也只是粗略的记录下原理,贴下模板,以及入门题目(感受下模板怎么用的) (PS:文中蓝色字体都可以点进去查看百度原文) 附赠数论入门训练专题:点我打开专题(题目顺序基本正常,用以配套数论入门) 一.同余定理 简单粗暴的说就是:若 a-b == m 那么 a%m == b%m 这个模运算性质一眼看出...直接上入门水题: Reduced ID Numbers 附AC代码(这个也没啥模板....知道就好) #inclu

POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the num

HDU1164_Eddy&amp;#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.

HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime