扩展欧拉定理

扩展欧拉定理

欧拉函数 ϕ

ϕ(x)[1,x] 范围内和 x 互质的数的数量.

对于质数 x, 由于和 [1,x1] 中任意数字互质, 所以有结论

ϕ(x)=x1

对于正整数 x, pi 表示第 i 个质数, 由正整数的唯一分解设

x=ipi|xpiai

由于被 pi 整除的数有 x/pi 个, 这些数一定不和 x 互质. 结合容斥原理, 对于所有的 pi|x, 和 x 互质的数有

ipi|xxpii,jpipj|xxpipj+i,j,kpipjpk|xxpipjpk...

提公因式:

x(ipi|x1pii,jpipj|x1pipj+i,j,kpipjpk|x1pipjpk...)

整理得

ϕ(x)=xipi|x(11pi)

x=ab, gcd(a,b)=1

ϕ(a)=aipi|a(11pi)ϕ(b)=bipi|b(11pi)

把两式相乘

ϕ(a)ϕ(b)=abipi|aipi|b

已知 pi|api|b 不能同时满足, 又因为 x=ab, 所以只要 pi|b or pi|a, 当且仅当 pi|x, 上式变成

ϕ(a)ϕ(b)=xipi|x=ϕ(x)

因此得出结论, 对于 x=ab, gcd(a,b)=1, 有

ϕ(x)=ϕ(a)ϕ(b)

我们把 ϕ(x) 这种性质称作 积性函数

欧拉定理

设正整数 a, p 互质

aϕ(p) % p=1

由此可以推得费马小定理, 即对于正整数 a 和质数 p, 有

aϕ(p) % p=ap1 % p=1

这就是快速幂求乘法逆元的原理

扩展欧拉定理

前置知识

  • 引理一, 设正整数 x, a1, a2, a3, ..., an, 如果 xy(mod ai), 则有

xy(mod lcm(ai))xy(mod iai)

  • 引理二, 设质数 p, 正整数 x>1, 则

ϕ(px)=px(11p)=pxpxp=pxpx1x

证明

设正整数 q, a, x, 质数 p, 满足 xϕ(pq)

由于 p 是质数, 所以对于 gcd(a,p), 有两种情况, 即 1p.

  • 针对 gcd(a,p)=1 的情况, 一定有 gcd(ax,pq)=1, 根据欧拉定理, aϕ(pq) % pq=1, 所以一定有

ax % pq=ax % ϕ(pq) % pq=(a(x % ϕ(pq))+ϕ(pq)) % pq

  • 针对 gcd(a,p)=p 的情况, 由引理二得 xϕ(pq)q. 一定有 ax % pq=aϕ(pq) % pq=0. 所以

(ax % ϕ(pq)aϕ(pq)) % pq=(a(x % ϕ(pq))+ϕ(pq)) % pq=0=ax % pq

综上, 对于所有正整数 q, a, x, 质数 p, (xϕ(pq)), 有

ax % pq=(a(x % ϕ(pq))+ϕ(pq)) % pq

设正整数 m, 将其拆分为质因数对应幂的乘积, 由引理一和 ϕ(x) 的积性函数性质得

x % ϕ(piqi)=x % lcm(ϕ(piqi))=x % ϕ(m)

因为 xϕ(m), 所以对于所有 i 满足 pi|m, 有

x % ϕ(piqi)=x % ϕ(m)

因此

axax % ϕ(m)+ϕ(m) (mod piqi)

再次利用引理一, 得到

axax % ϕ(m)+ϕ(m) (mod m)

这就是扩展欧拉定理

模板 Luogu5091

ab % m, (1a109,1b102107,1m108)

根据扩展欧拉定理

ab % m=ab % ϕ(m)+ϕ(m) % m

易证

x % p=(((x % 10k) % p)10k+(x / 10k)) % p

所以 bϕ(m) 取模, 可以在快读过程中不断取模避免高精

值得一提的是, 本题中可能出现 b<ϕ(m) 的情况, 这时, ab % ϕ(m)+ϕ(m) 是错误的, 应该是 ab % ϕ(m), 所以读入时也要判断 b, m 的大小关系.

while (ch < '0' || ch > '9') {
  ch = getchar();
}
while (ch >= '0' && ch <= '9') {
  B *= 10;
  B += ch - '0';
  if(B > C) {
    flg = 1;
    B %= C;
  }
  ch = getchar();
}

关于求 phi(m), 由于只求一个数, 且 m108, 所以线性筛就不好使了, 用下面的式子求出 phi(m) (先除后乘防溢出)

ϕ(x)=xipi|x(11pi)

unsigned Phi(unsigned x) {
  unsigned tmp(x), anotherTmp(x), Sq(sqrt(x));
  for (register unsigned i(2); i <= Sq && i <= x; ++i) {
    if(!(x % i)) {
      while (!(x % i)) {
        x /= i;
      }
      tmp /= i;
      tmp *= i - 1;
    }
  }
  if (x > 1) {//存在大于根号 x 的质因数 
    tmp /= x;
    tmp *= x - 1;
  }
  return tmp;
}

这里要说明一下为什么枚举到 n, 把这些质因数除掉后剩下的 n 一定是质数. 首先, nn, 如果是合数, 一定存在因数 p 使得 pnnn/pnn, 而这个 pn/p 至少有一个已经被枚举到了, 所以 n 不可能是合数.

最后便是求乘积了, 用最普通的取模快速幂完成这个任务

unsigned Power(unsigned x, unsigned y) {
  if(!y) {
    return 1;
  }
  unsigned tmp(Power(x, y >> 1));
  tmp = ((long long)tmp * tmp) % D;
  if(y & 1) {
    return ((long long)tmp * x) % D;
  }
  return tmp;
}

最后是加了一点特判的完整 main()

int main() {
  A = RD();
  D = RD();
  C = Phi(D);
  while (ch < '0' || ch > '9') {
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    B *= 10;
    B += ch - '0';
    if(B > C) {
      flg = 1;
      B %= C;
    }
    ch = getchar();
  }
  if(B == 1) {
    printf("%u\n", A % D);
    return Wild_Donkey;
  }
  if(flg) {
    printf("%u\n", Power(A, B + C));
  }
  else {
    printf("%u\n", Power(A, B));
  }
  return Wild_Donkey;
}
posted @   Wild_Donkey  阅读(370)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-03-14 数论: 莫比乌斯反演 ( 三 ) 证明
点击右上角即可分享
微信分享提示