您的位置:首页 > 其它

大素数,大整数质因数分解模板

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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: