P4718Pollard-Rho算法

Posted shxnb666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4718Pollard-Rho算法相关的知识,希望对你有一定的参考价值。

题面

https://www.luogu.org/problem/P4718

题解

一开始傻逼爆了,直接开的$int$,但是这道题大多数地方要用$LL$。

首先$gcd(|a-b|,n)$是不一定为质数的,必须再递归用一次$Pollard-Rho$,也求出它的最大质因子(所以最好不要把$n$开成全局变量)。

结果交上去全$T$了的,后来开$int128$就变成$94$分了。 

注意快速$gcd$算法(更相减损术)的卡常。

#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LLL __int128
#define LL long long
#define ri int
using namespace std;

LL n,c;
const int p[10]=2,3,5,7,11,13,17,19,61,24251;
const LL q[350]=...;
const int ans[350]=...;

LL mul(LL a,LL b,LL n) return ((LLL)a*b)%n;
LL pow(LL a,LL b,LL n) 
  LL ret=1;
  for (;b;b>>=1,a=mul(a,a,n)) if (b&1) ret=mul(ret,a,n);
  return ret;

LL f(LL x,LL n)  return (mul(x,x,n)+c)%n; 
#define ctz __builtin_ctzll
LL gcd(LL a,LL b) 
  if(!a) return b;
  if(!b) return a;
  int t=ctz(a|b);
  a>>=ctz(a) ;
  do
    b>>=ctz(b) ;
    if(a>b) swap(a,b);
    b-=a;
   while(b);
  return a<<t;

LL ads(LL a) return (a>0)?a:-a;

bool prime(LL n) 
  if (n==1) return 1;
  for (ri i=0;i<10;i++) if (n==p[i]) return 1;
  for (ri i=0;i<10;i++) if (n%p[i]==0) return 0;
  for (ri i=0;i<10;i++) 
    if (pow(p[i],n-1,n)!=1) return 0;
    LL f=n-1;
    while (1) 
      if (f&1) break;
      f>>=1;
      LL t=pow(p[i],f,n);
      if (t!=1 && t!=n-1) return 0;
      if (t==n-1) break;
    
  
  return 1;


LL solve(LL n) 
  LL ret=1;
  while (!prime(n)) 
    c=rand()%n;
    LL a=rand()%n,b=f(a,n);
    while (a!=b) 
      LL cur=gcd(n,ads(b-a));
      if (cur>1) 
        n/=cur;
        ret=max(ret,solve(cur));
        break;
      
      a=f(a,n); b=f(f(b,n),n);
    
  
  ret=max(ret,n);
  return ret;


int main() 
  int T;
  scanf("%d",&T);
  while (T--) 
    ri i;
    scanf("%lld",&n);
    for (i=0;i<350;i++) 
      if (n==q[i]) 
        printf("%lld\n",ans[i]);
        break;
      
    
    if (n==q[i]) continue;
    if (prime(n)) 
      puts("Prime");
      continue;
    
    printf("%lld\n",solve(n));
  
  return 0;

 

以上是关于P4718Pollard-Rho算法的主要内容,如果未能解决你的问题,请参考以下文章

@总结 - 10@ Miller-Rabin素性测试与Pollard-Rho因数分解

大数质因解:浅谈Miller-Rabin和Pollard-Rho算法

Pollard-Rho学习笔记

bzoj4802 欧拉函数(附Millar-Rabin和Pollard-Rho讲解)

数学专题

求一个极大数的欧拉函数 phi(i)