hdu 3864 素数分解

题意:求n是否只有4个因子,如果是就输出除1外的所有因子。

模板题,就不排版了

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 #include<ctime>
  9 using namespace std;
 10 #define MOD 1000000007
 11 const int INF=0x3f3f3f3f;
 12 const double eps=1e-5;
 13 #define cl(a) memset(a,0,sizeof(a))
 14 #define ts printf("*****\n");
 15 const int MAXN=1005;
 16 int n,m,tt;
 17 const int S = 8; //随机算法判定次数,一般8~10就够了
 18 // 计算ret = (a*b)%c a,b,c < 2^63
 19 long long mult_mod(long long a,long long b,long long c)
 20 {
 21 a %= c;
 22 b %= c;
 23 long long ret = 0;
 24 long long tmp = a;
 25 while(b)
 26 {
 27 if(b & 1)
 28 {
 29 ret += tmp;
 30 if(ret > c)ret -= c;//直接取模慢很多
 31 }
 32 tmp <<= 1;
 33 if(tmp > c)tmp -= c;
 34 b >>= 1;
 35 }
 36 return ret;
 37 }
 38 // 计算 ret = (a^n)%mod
 39 long long pow_mod(long long a,long long n,long long mod)
 40 {
 41 long long ret = 1;
 42 long long temp = a%mod;
 43 while(n)
 44 {
 45 if(n & 1)ret = mult_mod(ret,temp,mod);
 46 temp = mult_mod(temp,temp,mod);
 47 n >>= 1;
 48 }
 49 return ret;
 50 }
 51 // 通过 a^(n-1)=1(mod n)来判断n是不是素数
 52 // n-1 = x*2^t 中间使用二次判断
 53 // 是合数返回true, 不一定是合数返回false
 54 bool check(long long a,long long n,long long x,long long t)
 55 {
 56 long long ret = pow_mod(a,x,n);
 57 long long last = ret;
 58 for(int i = 1;i <= t;i++)
 59 {
 60 ret = mult_mod(ret,ret,n);
 61 if(ret == 1 && last != 1 && last != n-1)return true;//合数
 62 last = ret;
 63 }
 64 if(ret != 1)return true;
 65 else return false;
 66 }
 67 //**************************************************
 68 // Miller_Rabin算法
 69 // 是素数返回true,(可能是伪素数)
 70 // 不是素数返回false
 71 //**************************************************
 72 bool Miller_Rabin(long long n)
 73 {
 74 if( n < 2)return false;
 75 if( n == 2)return true;
 76 if( (n&1) == 0)return false;//偶数
 77 long long x = n - 1;
 78 long long t = 0;
 79 while( (x&1)==0 ){x >>= 1; t++;}
 80 srand(time(NULL));/* *************** */
 81 for(int i = 0;i < S;i++)
 82 {
 83 long long a = rand()%(n-1) + 1;
 84 if( check(a,n,x,t) )
 85 return false;
 86 }
 87 return true;
 88 }
 89 //**********************************************
 90 // pollard_rho 算法进行质因素分解
 91 //
 92 //
 93 //*********************************************
 94 long long factor[100];//质因素分解结果(刚返回时时无序的)
 95 int tol;//质因素的个数,编号0~tol-1
 96 long long gcd(long long a,long long b)
 97 {
 98 long long t;
 99 while(b)
100 {
101 t = a;
102 a = b;
103 b = t%b;
104 }
105 if(a >= 0)return a;
106 else return -a;
107 }
108 //找出一个因子
109 long long pollard_rho(long long x,long long c)
110 {
111 long long i = 1, k = 2;
112 srand(time(NULL));
113 long long x0 = rand()%(x-1) + 1;
114 long long y = x0;
115 while(1)
116 {
117 i ++;
118 x0 = (mult_mod(x0,x0,x) + c)%x;
119 long long d = gcd(y - x0,x);
120 if( d != 1 && d != x)return d;
121 if(y == x0)return x;
122 if(i == k){y = x0; k += k;}
123 }
124 }
125 //对 n进行素因子分解,存入factor. k设置为107左右即可
126 void findfac(long long n,int k)
127 {
128 if(n == 1)return;
129 if(Miller_Rabin(n))
130 {
131 factor[tol++] = n;
132 return;
133 }
134 long long p = n;
135 int c = k;
136 while( p >= n)
137 p = pollard_rho(p,c--);//值变化,防止死循环k
138 findfac(p,k);
139 findfac(n/p,k);
140 }
141 //POJ 1811
142 //给出一个N(2 <= N < 2^54),如果是素数,输出"Prime",否则输出最小的素因子
143 int main()
144 {
145     int T;
146     long long n;
147     #ifndef ONLINE_JUDGE
148     freopen("1.in","r",stdin);
149     #endif
150     while(scanf("%I64d",&n)==1)
151     {
152         if(n==1)
153         {
154             printf("is not a D_num\n");
155             continue;
156         }
157         tol=0;
158         findfac(n,107);
159         if(tol!=2 && tol!=3)
160         {
161             printf("is not a D_num\n");
162             continue;
163         }
164         sort(factor,factor+tol);
165         if(tol==2)
166         {
167             if(factor[0]!=factor[1])
168             {
169                 printf("%I64d %I64d %I64d\n",factor[0],factor[1],factor[0]*factor[1]);
170                 continue;
171             }
172             else
173             {
174                 printf("is not a D_num\n");
175                 continue;
176             }
177         }
178         if(tol==3)
179         {
180             if(factor[0]==factor[1]&&factor[1]==factor[2])
181             {
182                 printf("%I64d %I64d %I64d\n",factor[0],factor[0]*factor[1],factor[0]*factor[1]*factor[2]);
183                 continue;
184             }
185             else
186             {
187                 printf("is not a D_num\n");
188                 continue;
189             }
190         }
191     }
192     return 0;
193 }
时间: 2024-12-22 19:36:17

hdu 3864 素数分解的相关文章

HDU 3864 D_num Miller Rabin 质数判断+Pollard Rho大整数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864 题意:给出一个数N(1<=N<10^18),如果N只有四个约数,就输出除1外的三个约数. 思路:大数的质因数分解只能用随机算法Miller Rabin和Pollard_rho,在测试多的情况下正确率是由保证的. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <c

hdu 2012 素数判定 Miller_Rabbin

素数判定 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 71785    Accepted Submission(s): 24969 Problem Description 对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数. Input 输入数据

校队训练赛,同时也是HDU4497(数论:素数分解+组合数学)

一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=4497 二.思路 将满足条件的一组x,z,y都除以G,得到x‘,y',z',满足条件gcd(x',y',x') = 1,同时lcm(x',y',x') = G/L.特判,当G%L != 0 时,无解.然后素数分解G/L,假设G/L = p1^t1 * p2^t2 *````* pn^tn.满足上面条件的x,y,z一定为这样的形式.x' = p1^i1 * p2^i2 *```* pn^in.y' =

hdu 1299 数论 分解素因子

题意:求1.1/x+1/y=1/z 给定z 求x,y的个数zsd:1: 要知道这个素数的因子的范围 范围为2--sqrt(n);2: 带入方程得:x = n * n / k + n ; 现在就变成了求x的值.又因为n一定大于k,所以转换成求n * n的分解数: 因为n = p1 ^ e1 * p2 ^ e2 *..........*pn ^ en sum ( n)= ( 1 + e1 ) * ( 1 +e2 ) * .........* ( 1 +en ); sum (n * n) = ( 1

hdu 1012 素数判定

这道题~以前判定prime是一个个去试着整除再去存储,上次弄过欧拉函数那题目之后就知道了,这样会更快捷: 1 prime[0] = prime[1] = 1; 2 for(int i = 2; i <maxn; i++) 3 { 4 if(!prime[i]) 5 { 6 for(int j = i * 2; j < maxn; j += i) 7 prime[j] = 1; 8 } 9 } 以下是AC代码~~~水水题~ 1 #include<iostream> 2 #includ

算法15---数论6---素数,回文素数 分解质因素

算法15---数论6---素数,回文素数  分解质因素 1 /* 2 题目:素数,回文素数 3 author taoliu——alex 2016.10 number4 4 5 主要实现: 6 判断素数,判断回文素数 7 */ 8 9 10 11 #include <stdio.h> 12 #include <math.h> 13 14 15 16 //素数 17 18 19 int isprime(int a) 20 { 21 for (int i = 2; i < a; i

light_oj 1220 素数分解

light_oj 1220  素数分解 J - Mysterious Bacteria Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1220 Description Dr. Mob has just discovered a Deathly Bacteria. He named it RC-01. RC-01 has a very

hdu 5317 合数分解+预处理

RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2818    Accepted Submission(s): 1108 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and m

求最大公约数的两种解法(欧几里得算法和素数分解)

最大公约数的两种解法(欧几里得算法和素数分解) 方法一: 欧几里得算法,又称辗转相除法 定理(欧几里得算法):设a和b是正整数,则存在最大求最大公因子d=(a,b)的一种算法,且存在求一组整数s,t使得d = sa+tb 举个例子:求168和60的最大公约数? 168 = 2 * 60 + 48 60  = 1 * 48 +12 48  = 4 * 12 由此得最大公约数为12 关于最大公倍数 C语言程序代码:很简单就不加注释了 #include<stdio.h> #define SWAP(a