拓展欧拉定理学习笔记

拓展欧拉定理

内容

对于 \(a,m\in \mathbb{Z}\),有 \(a^b \equiv \begin{cases}a^b&b< \varphi(m) \\a^{\left( b \bmod \varphi(m) \right)+\varphi(m)}&b>\varphi(m)\end{cases} \pmod{p}\)

证明

模板

P5091 【模板】扩展欧拉定理

给定三个数 \(a,m,b\in\mathbb{Z}\),求 \(a^b \bmod m\)
\(1 \le m \le 10^8,1 \le b \le 10^{20000000}, 1 \le a \le 10^9\)

首先根据拓展欧拉定理的内容,先求出 \(\varphi(m)\)

int ph(int x){
	int s=x;
    for(int i=2;i*i<=x;i++)if(x%i==0){s-=s/i;while(x%i==0)x/=i;}
	if(x>1)s-=s/x;return s;
}

至于 \(b\) 的读入,考虑按位读入,读入的同时取模并判断是否大于 \(\varphi(m)\)

int rd(){
	int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9'){x*=10,x+=(c^'0');if(x>=mod)f=1;x%=mod;c=getchar();}return x;
}

剩下的就是一个快速幂了,因为全定义了全局变量所以没有传参。

int ksm(){int s=1,g=a;while(b){if(b&1)s=s*g%m;b>>=1;g=g*g%m;}return s;}

最后放一下完整代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;int mod,a,m,b,f;int ph(int x){
	int s=x;for(int i=2;i*i<=x;i++)if(x%i==0){s-=s/i;while(x%i==0)x/=i;}
	if(x>1)s-=s/x;return s;
}int ksm(){int s=1,g=a;while(b){if(b&1)s=s*g%m;b>>=1;g=g*g%m;}return s%m;}int rd(){
	int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9'){x*=10,x+=(c^'0');if(x>=mod)f=1;x%=mod;c=getchar();}return x;
}signed main(){cin>>a>>m;mod=ph(m);b=rd();if(f)b+=mod;cout<<ksm();}

To be continued……

posted @ 2022-05-12 10:16  AIskeleton  阅读(21)  评论(0编辑  收藏  举报