题意:判断所有质数i<=k,2^i-1是否是质数,不是的话就要将它分解质因数输出来。
题解:miller_rabin判,pollard-pho分解,基本就是枚举,也可以打表。
View Code
1 #include<ctime> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 using namespace std; 7 long long factor[100],fac_top = -1; 8 //计算两个数的gcd 9 long long ran[1000000],ID; 10 long long Rand() 11 { 12 srand(ran[ID++%1000000]); 13 return rand(); 14 } 15 long long gcd(long long a,long long b) 16 { 17 if(a==0) 18 return b; 19 long long c; 20 while(b!=0) 21 { 22 c=b; 23 b=a%b; 24 a=c; 25 } 26 return a; 27 } 28 //ret = (a*b)%n (n<2^62) 29 long long muti_mod(long long a,long long b,long long n) 30 { 31 long long exp = a%n, res = 0; 32 while(b) 33 { 34 if(b&1) 35 { 36 res += exp; 37 if(res>n) res -= n; 38 } 39 exp <<= 1; 40 if(exp>n) 41 exp -= n; 42 43 b>>=1; 44 } 45 return res; 46 } 47 // ret = (a^b)%n 48 long long mod_exp(long long a,long long p,long long m) 49 { 50 long long exp=a%m, res=1; // 51 while(p>1) 52 { 53 if(p&1)// 54 res=muti_mod(res,exp,m); 55 exp = muti_mod(exp,exp,m); 56 p>>=1; 57 } 58 return muti_mod(res,exp,m); 59 } 60 //miller-rabin法测试素数, time 测试次数 61 bool miller_rabin(long long n, long long times) 62 { 63 if(n==2)return 1; 64 if(n<2||!(n&1))return 0; 65 66 long long a, u=n-1, x, y; 67 int t=0; 68 while(u%2==0) 69 { 70 t++; 71 u/=2; 72 } 73 for(int i=0; i<times; i++) 74 { 75 a = Rand() % (n-1) + 1; 76 x = mod_exp(a, u, n); 77 for(int j=0; j<t; j++) 78 { 79 y = muti_mod(x, x, n); 80 if ( y == 1 && x != 1 && x != n-1 ) 81 return false; 82 x = y; 83 } 84 if( y!=1) return false; 85 } 86 return true; 87 } 88 long long pollard_rho(long long n,int c) 89 { 90 long long x,y,d,i = 1,k = 2; 91 x = Rand()%(n-1)+1; 92 y = x; 93 while(true) 94 { 95 i++; 96 x = (muti_mod(x,x,n) + c) % n; 97 d = gcd(y-x, n); 98 if(1 < d && d < n) 99 return d; 100 if( y == x) 101 return n; 102 if(i == k) 103 { 104 y = x; 105 k <<= 1; 106 } 107 } 108 } 109 void findFactor(long long n,int k) 110 { 111 if(n==1)return; 112 if(miller_rabin(n, 6)) 113 { 114 factor[++fac_top] = n; 115 return; 116 } 117 long long p = n; 118 while(p >= n) 119 p = pollard_rho(p,k--); 120 findFactor(p,k); 121 findFactor(n/p,k); 122 } 123 int main() 124 { 125 for(int tt=0; tt<1000000; tt++) 126 ran[tt]=tt; 127 random_shuffle(ran,ran+1000000); 128 int k; 129 while(scanf("%d",&k)!=EOF) 130 { 131 for(int i=11; i<=k; i++) 132 { 133 ID=0; 134 if(!miller_rabin((long long)i,30)) 135 continue; 136 long long n=(1ll<<i)-1; 137 ID=0; 138 fac_top=-1; 139 if(!miller_rabin(n,30)) 140 { 141 findFactor(n,107); 142 sort(factor,factor+fac_top+1); 143 for(int j=0; j<fac_top; j++) 144 printf("%lld * ",factor[j]); 145 printf("%lld = %lld = ( 2 ^ %d ) - 1\n",factor[fac_top],n,i); 146 } 147 } 148 } 149 return 0; 150 }