大素数测试和分解质因数
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 fac[128];//每种质因数 64 int num[128];//每种对应的个数 65 int flen;//质因素的种数 66 void findfac(LL n,int k) { 67 if(n==1) return; 68 if(isprime(n)) { 69 fac[flen++]=n; 70 return ; 71 } 72 LL p=n; 73 int c=k; 74 while(p>=n) { 75 p=pollard_rho(p,c--); 76 } 77 findfac(p,k); 78 findfac(n/p,k); 79 } 80 void gxfindfac(LL n){//大数分解质因数 81 flen=0; 82 findfac(n,120); 83 sort(fac,fac+flen); 84 num[0]=1; 85 int k=1; 86 for(int i=1;i<flen;i++){ 87 if(fac[i]==fac[i-1]){ 88 num[k-1]++; 89 } 90 else{ 91 num[k]=1; 92 fac[k++]=fac[i]; 93 } 94 } 95 flen=k; 96 } 97 int main(){ 98 int t; 99 LL n; 100 while(~scanf("%d",&t)){ 101 while(t--){ 102 scanf("%I64d",&n); 103 if(isprime(n)){ 104 puts("Prime"); 105 continue; 106 } 107 gxfindfac(n); 108 printf("%I64d\n",fac[0]); 109 } 110 } 111 return 0; 112 }
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 }
Pseudoprime numbers http://acm.hdu.edu.cn/showproblem.php?pid=1905
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 LL p,a; 46 while(~scanf("%I64d%I64d",&p,&a),p|a){ 47 if(!isprime(p)&&powmod(a,p,p)==a){ 48 puts("yes"); 49 } 50 else{ 51 puts("no"); 52 } 53 } 54 return 0; 55 }
Mark the Rope http://acm.hdu.edu.cn/showproblem.php?pid=4344
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 64 LL fac[128];//每种质因数 65 int num[128];//每种对应的个数 66 int flen;//质因素的种数 67 void findfac(LL n,int k) { 68 if(n==1) return; 69 if(isprime(n)) { 70 fac[flen++]=n; 71 return ; 72 } 73 LL p=n; 74 int c=k; 75 while(p>=n) { 76 p=pollard_rho(p,c--); 77 } 78 findfac(p,k); 79 findfac(n/p,k); 80 } 81 void gxfindfac(LL n){ 82 flen=0; 83 findfac(n,120); 84 sort(fac,fac+flen); 85 num[0]=1; 86 int k=1; 87 for(int i=1;i<flen;i++){ 88 if(fac[i]==fac[i-1]){ 89 num[k-1]++; 90 } 91 else{ 92 num[k]=1; 93 fac[k++]=fac[i]; 94 } 95 } 96 flen=k; 97 } 98 int main() 99 { 100 int t; 101 LL n; 102 while(~scanf("%d",&t)){ 103 while(t--){ 104 scanf("%I64d",&n); 105 gxfindfac(n); 106 LL ans=0; 107 for(int i=0;i<flen;i++){ 108 LL tmp=1; 109 for(int j=0;j<num[i];j++){ 110 tmp*=fac[i]; 111 } 112 ans+=tmp; 113 } 114 if(flen==1) ans/=fac[0]; 115 printf("%d %I64d\n",flen,ans); 116 } 117 } 118 return 0; 119 }
D_num http://acm.hdu.edu.cn/showproblem.php?pid=3864
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 fac[128];//每种质因数 64 int num[128];//每种对应的个数 65 int flen;//质因素的种数 66 void findfac(LL n,int k) { 67 if(n==1) return; 68 if(isprime(n)) { 69 fac[flen++]=n; 70 return ; 71 } 72 LL p=n; 73 int c=k; 74 while(p>=n) { 75 p=pollard_rho(p,c--); 76 } 77 findfac(p,k); 78 findfac(n/p,k); 79 } 80 void gxfindfac(LL n){//大数分解质因数 81 flen=0; 82 findfac(n,120); 83 if(!flen) return ; 84 sort(fac,fac+flen); 85 num[0]=1; 86 int k=1; 87 for(int i=1;i<flen;i++){ 88 if(fac[i]==fac[i-1]){ 89 num[k-1]++; 90 } 91 else{ 92 num[k]=1; 93 fac[k++]=fac[i]; 94 } 95 } 96 flen=k; 97 } 98 int main(){ 99 LL n; 100 while(~scanf("%I64d",&n)){ 101 gxfindfac(n); 102 int all=0; 103 for(int i=0;i<flen;i++){ 104 all+=num[i]; 105 } 106 if(all==2){ 107 if(flen==2){ 108 printf("%I64d %I64d %I64d\n",fac[0],fac[1],fac[0]*fac[1]); 109 continue; 110 } 111 } 112 if(all==3){ 113 if(flen==1){ 114 printf("%I64d %I64d %I64d\n",fac[0],fac[0]*fac[0],fac[0]*fac[0]*fac[0]); 115 continue; 116 } 117 } 118 puts("is not a D_num"); 119 } 120 return 0; 121 }
end