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 }