POJ 2191

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

你可能感兴趣的:(poj)