hdu3864 Miller_Rabin快速判断素数&Pollard_rho快速分解素因数

额随机开了场多校,做到第二题傻眼了。。这么大的数据搞毛线===

试着来了一发暴力T了,没有尝试随机(我来瞅瞅题解

==

看到了新的算法,哎欠的终究要补,把Miller_Rabin和Pollard_rho算法看了一晚上---->并看不懂2333

其实大部分还是可以看懂的,主要就是Miller_Rabin那里的二次探测和Pollard_rho循环i==k不太理解==

先学着别人代码打了一发(卧槽因为gcd那边写错了T到死

明天再来研究这些细节方面,有时间就做做题==

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<time.h>
  4 #include<string.h>
  5 #include<algorithm>
  6 #define LL long long
  7 using namespace std;
  8 LL tot,factor[2005];//n的因子
  9 LL gcd(LL a,LL b)
 10 {
 11   if (a==0) return 1;//联系下文
 12   if (b==0) return a;
 13   return gcd(b,a%b);
 14 }
 15 LL mul(LL a,LL b,LL mod)//快速乘法
 16 {
 17   LL ans=0;
 18   a%=mod; b%=mod;
 19   while (b)
 20   {
 21     if (b%2) {ans=(ans+a); if (ans>=mod) ans-=mod; }
 22     a*=2; if (a>=mod) a-=mod;
 23     b/=2;
 24   }
 25   return ans;
 26 }
 27 LL quick(LL x,LL n,LL mod)//快速幂
 28 {
 29   LL ans=1;
 30   x%=mod;
 31   while (n)
 32   {
 33     if (n%2==1) ans=mul(ans,x,mod);
 34     x=mul(x,x,mod);
 35     n/=2;
 36   }
 37   return ans;
 38 }
 39 int miller_rabbin(LL n)//判断素数
 40 {
 41   if (n==2) return 1;
 42   if (n<2||n%2==0) return 0;
 43   LL x=n-1,t=0;
 44   LL i,j,ret,last,a;
 45   while (x%2==0) {x/=2; t++;}
 46   for (i=0;i<10;i++)
 47   {
 48     a=rand()%(n-1)+1;
 49     ret=quick(a,x,n);
 50     last=ret;
 51     for (j=1;j<=t;j++)//二次探测
 52     {
 53       ret=mul(ret,ret,n);
 54       if (ret==1&&last!=1&&last!=n-1) return 0;
 55       last=ret;
 56     }
 57     if (ret!=1) return 0;//费马小定理
 58   }
 59   return 1;
 60 }
 61 LL pollard_rho(LL x,LL c)//寻找一个因子
 62 {
 63   LL i,k,x1,y,d;
 64   i=1; k=2; x1=rand()%x; y=x1;
 65   while (1)
 66   {
 67     i++;
 68     x1=(mul(x1,x1,x)+c)%x;
 69     d=gcd(abs(y-x1),x);
 70     if (d!=1&&d!=x) return d;
 71     if (y==x1) return x;
 72     if (i==k){ y=x1; k*=2;}
 73   }
 74 }
 75 void find(LL n)//素因子分解
 76 {
 77   if (miller_rabbin(n))
 78   {
 79     factor[++tot]=n;
 80     return;
 81   }
 82   LL p=n;
 83   while (p>=n) p=pollard_rho(p,rand()%(n-1)+1);
 84   find(p);
 85   find(n/p);
 86 }
 87 int main()
 88 {
 89   LL n;
 90   srand(time(NULL));
 91   while (~scanf("%I64d",&n))
 92   {
 93     if (n==1)
 94     {
 95       printf("is not a D_num\n");
 96       continue;
 97     }
 98     tot=0; find(n);
 99     if (tot!=2&&tot!=3)
100     {
101       printf("is not a D_num\n");
102       continue;
103     }
104     //两种情况
105     if (tot==2&&factor[1]!=factor[2])
106       printf("%I64d %I64d %I64d\n",
107           min(factor[1],factor[2]),max(factor[1],factor[2]),n);
108     else if (tot==3&&factor[1]==factor[2]&&factor[2]==factor[3])
109       printf("%I64d %I64d %I64d\n",factor[1],factor[1]*factor[2],n);
110     else printf("is not a D_num\n");
111   }
112   return 0;
113 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864

posted on 2015-04-30 01:48  xiao_xin  阅读(183)  评论(0编辑  收藏  举报

导航