大素数,大整数质因数分解模板
2015-08-11 16:17
531 查看
#include <stdio.h> #include <algorithm> #include <math.h> #include <stdlib.h> #include <string.h> #include <time.h> using namespace std; typedef __int64 LL ; LL pri[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47}; LL ans[100005], flag; LL gcd(LL a, LL b) { //最大公因式求解模板 while (b) { LL c = a % b; a = b; b = c; } return a; } LL multi(LL a, LL b, LL n) { //(a*b) mod n 模板 LL tmp = 0; while (b) { if (b & 1) { tmp += a; if (tmp >= n) tmp -= n; } a <<= 1; if (a >= n) a -= n; b >>= 1; } return tmp; } LL multimod(LL a, LL m, LL n) { //a^m mod n 模板 LL tmp = 1; a %= n; while (m) { if (m & 1) tmp = multi(tmp, a, n); a = multi(a, a, n); m >>= 1; } return tmp; } bool MiLLer_Rabin(LL n) { 素数判定模板 if (n < 2) return 0; if (n == 2) return 1; if (!(n & 1)) return 0; LL k = 0, i, j, m, a; m = n - 1; while (!(m & 1)) m >>= 1, k++; for (i = 0; i < 10; i++) { if (pri[i] >= n) return 1; a = multimod(pri[i], m, n); if (a == 1) continue; for (j = 0; j < k; j++) { if (a == n - 1) break; a = multi(a, a, n); } if (j == k) return 0; } return 1; } LL poLLard_rho(LL c, LL n) { LL i, x, y, k, d; i = 1; x = y = rand() % n; k = 2; do { i++; d = gcd(n + y - x, n); if (d > 1 && d < n) return d; if (i == k) y = x, k <<= 1; x = (multi(x, x, n) + n - c) % n; } while (y != x); return n; } void rho(LL n) { //大整数因式分解模板 if (MiLLer_Rabin(n)) { ans[flag] = n; flag++; return; } LL t = n; while (t >= n) t = poLLard_rho(rand() % (n - 1) + 1, n); rho(t); rho(n / t); return; } int main() { LL n; while(scanf("%I64d",&n) != EOF){ if( n == -1 ) break; if( n == 1 ) { puts( "0" ) ;continue ; } if( n == 2 ) { puts( "1" ) ;continue ; } if(n != 4 && n % 4 == 0){ printf("1\n"); continue; } if(n%2 == 0){ flag = 0 ;rho(n/2); sort( ans , ans + flag ) ; bool ok ; if( ans[0] == ans[flag-1] ) ok = true ; else ok = false ; if( ok ){ printf("%I64d\n",n-1); continue; }else{ printf("1\n"); continue; } }else{ flag = 0 ;rho(n); sort( ans , ans + flag ) ; bool ok ; if( ans[0] == ans[flag-1] ) ok = true ; else ok = false ; if(ok){ printf("%I64d\n",n-1); continue; }else{ printf("1\n"); continue; } } } return 0 ; }
相关文章推荐
- android 集合架构
- Android音乐播放器---实现Notification控制音乐播放
- 编码详解
- 关于SBA(Sparse Bundle Adjustment)编译以及遇到的一些问题
- Java中的属性Properties
- 23-IO流-44-IO流(Properties集合的-store方法)
- C#调用C++的DLL搜集整理的所有数据类型转换方式
- SpringMVC+MyBatis整合(1)generator篇
- iOS 支付宝的集成与遇到的问题
- Entity Framework 异常档案
- POJ 3468 A Simple Problem with Integers 线段树
- iOS 9应用开发教程之显示编辑文本标签文本框
- js模拟Map
- js实现获取当前时间是本月第几周的方法
- HTML DOM top属性
- 反应堆模式的用法
- strcpy和memcpy的区别
- UVa 3266 Tian Ji -- The Horse Racing
- Posix线程私有数据
- [leetcode-112]Path Sum(java)