关于 pollard's rho 的倍增实现
  • 板块学术版
  • 楼主ppip嘟嘟嘟
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/5/10 22:45
  • 上次更新2023/10/23 16:07:55
查看原帖
关于 pollard's rho 的倍增实现
374433
ppip嘟嘟嘟楼主2023/5/10 22:45

本段代码来自oiwiki.

有如下朴素floyd判环代码:

ll Pollard_Rho(ll N) {
  ll c = rand() % (N - 1) + 1;
  ll t = f(0, c, N);
  ll r = f(f(0, c, N), c, N);
  while (t != r) {
    ll d = gcd(abs(t - r), N);
    if (d > 1) return d;
    t = f(t, c, N);
    r = f(f(r, c, N), c, N);
  }
  return N;
}

oi-wiki上给出了如下的倍增优化:

ll Pollard_Rho(ll x) {
  ll t = 0;
  ll c = rand() % (x - 1) + 1;
  // 加速算法,这一步可以省略
  for (int i = 1; i < 1145; ++i) t = f(t, c, x);
  ll s = t;
  int step = 0, goal = 1;
  ll val = 1;
  for (goal = 1;; goal <<= 1, s = t, val = 1) {
    for (step = 1; step <= goal; ++step) {
      t = f(t, c, x);
      val = val * abs(t - s) % x;
      // 如果 val 为 0,退出重新分解
      if (!val) return x;
      if (step % 127 == 0) {
        ll d = gcd(val, x);
        if (d > 1) return d;
      }
    }
    ll d = gcd(val, x);
    if (d > 1) return d;
  }
}

我想问的是,优化的目的是减小gcd调用的次数,那直接每个一个间隔就把这一段枚举的|s-t|乘起来和n取gcd就行了吧,为什么要改成倍增形式?

另外,为什么遇到val=0退出?不应该是t=s时退出吗?前者要更弱罢

2023/5/10 22:45
加载中...