题意:判断所有质数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 }