欧拉定理及其推论,裴蜀定理,计算欧拉函数
欧拉定理
内容:若正整数 \(a\),\(n\),互质,则 \(a^{\varphi (n)}\equiv 1 \pmod{n}\)。
证明:设 \(X_{1}\),\(X_{2}\)......\(X_{\varphi(n)}\) 是 \(1\sim n\) 与 \(n\) 互质的数。
首先我们来考虑一些数:\(aX_{1}\),\(aX_{2}\).....\(aX_{\varphi(n)}\)。
这些数有如下两个性质:
(1)任意两个数模 \(n\) 的余数一定不同。
证明:若存在 \(aX_{1}\equiv aX_{2} \pmod{n}\) 则存在 \(n\mid (aX_{1}-aX_{2})\),而 \(a\),\(n\) 互质,并且 \((aX_{1}-aX_{2})<n\),所以 \(n\) 不可能整除 \((aX_{1}-aX_{2})\) ,也就是说不存在 \(aX_{1}\equiv aX_{2} \pmod{n}\),所以对于任意的与 \(n\) 互质的 \(X_{i}\) 均成立。故得证。
那么因为有 \(\varphi(n)\) 个这样的数,\(X_{i}\pmod{n}(i=1 \sim \varphi(n))\) 所以就有 \(\varphi(n)\) 个不同的余数,并且模数分别为 \((0\sim n-1)\)。
(2)
对于任意的 \(aX_{i}\pmod{n}\) 都与 \(n\) 互质。这不难想,因为 \(a\) 与 \(n\) 互质是欧拉函数的条件,\(X_{i}\) 是 \((1\sim n)\) 与 \(n\) 互质的数的集合中的元素。所以如果 \(aX_{i}\) 作为分子,\(n\) 作为分母,那么他们构成的显然是一个最简分数,也就是说 \(aX_{i}\) 和 \(n\) 互质。接下来就可以用欧几里得算法:因为 \(\gcd(aX_{i},n)=1\) 所以 \(\gcd(aX_{i},n)=\gcd(n,aX_{i}\bmod n)=1\)。
把上面两个性质结合一下来说,\(aX_{1}\pmod{n}\) ,\(aX_{2}\pmod{n}\)....\(aX_{\varphi(n)}\pmod{n}\) 构成了一个集合(性质1已经证明了所有元素的互异性),并且这些数是 \(1\sim n\) 与 \(n\) 互质的所有数构成的集合(性质1已经说明)。这样,上述集合经过一定的排序后和集合 \(\{X_{1},X_{2}....X_{\varphi(n)}\}\) 完全一一对应,那么:\(aX_{1}\pmod{n}\times aX_{2}\pmod{n}\times....\times aX_{\varphi(n)}\pmod{n}=X_{1}\times X_{2}\times.....\times X_{\varphi(n)}\)。
因此我们可以写出以下式子:
\(aX_{1}\times aX_{2}\times....\times aX_{\varphi(n)}\equiv X_{1}\times X_{2}\times....\times X_{\varphi(n)}\pmod{n}\),
即:\((a^{\varphi(n)}-1)\times X_{1}\times X_{2}\times....\times X_{\varphi(n)}\equiv 0 \pmod{n}\)。
又因为 \(X_{1}\times X_{2}\times ....\times X_{\varphi(n)}\) 与 \(n\) 互质,所以 \((a^{\varphi(n)}-1)\mid n\),那么 \(a_{\varphi(n)}\equiv 1 \pmod{n}\)。欧拉定理得证。
裴蜀定理
定义:若 \(a\),\(b\) 是整数,且 \(\gcd(a,b)=d\),那么对于任意的整数 \(x\),\(y\),\(ax+by\) 都一定是 \(d\) 的倍数,特别的,一定存在整数 \(x\),\(y\),使 \(ax+by=d\) 成立。
简单来说,我们设 \(d=\gcd(a,b)\),那么对于方程 \(ax+by=d\),一定存在一组整数解,并且对于方程 \(ax+by=z\),如果满足 \(d\mid z\),那么方程一定有整数解,否则无整数解。
首先来证明一下 \(ax+by=d\) 有整数解(耐心看):
先不要去想那个式子,先来想一想怎么求 \(\gcd(a,b)\) 。
用辗转相除法对 \(8\)。
我们设 \(a\le b\),由辗转相除法的过程 \(\gcd(x,y)=\gcd(y,x \bmod y)\) 可以得到:
设 \(b=ax_{1}+r_{1}\),那么 \(b\bmod a\) 后 \(b=r_{1}\)。
重复此过程可以得到下面的式子:
\(b=ax_{1}+r_{1}\)
\(a=r_{1}x_{2}+r_{2}\)
\(.......\)
\(r_{k-3}=r_{k-2}x_{k-1}+r_{k-1}\) (1)
\(r_{k-2}=r_{k-1}x_{k}+r_{k}\) (2)
\(r_{k-1}=r_{k}x_{k+1}+r_{k+1}\)
因为辗转相除法最后得到的余数为 \(0\) 所以我们设 \(r_{k-1}=0\),那么 \(r_{k}\) 就是 \(a\) 和 \(b\) 的最大公约数,即 \(r_{k}=d\)。将 \(r_{k}=d\) 带入(2)中得:
\(r_{k-2}=r_{k-1}x_{k}+d\)
移项一下,得:
\(d=r_{k-2}-r_{k-1}x_{k}\) (3)
将(1)移项得:
\(r_{k-1}=r_{k-3}-r_{k-2}x_{k-1}\) (4)
将(4)带入(3)式得到:
\(d=r_{k-2}-(r_{k-3}-r_{k-2}x_{k-1})x_{k}\)
把式子展开后,可以表示成
\(d=r_{k-2}-r_{k-3}x_{k}+r_{k-2}x_{k-1}x_{k}\)
合并一下同类项,得:
\(d=r_{k-2}(x_{k-1}x_{k}+1)-r_{k-3}x_{k}\)
这系数有点长,换个字母代替一下:
\(d=m_{1}r_{k-2}+n_{1}r_{k-3}\)
简洁多了,上面所有的字母代表的都是整数,所以 \(m_{1}\),\(n_{1}\) 也一定是整数。
如果把(3)表示成 \(d=mr_{k-1}+nr_{k-2}\) 的话
\(d=mr_{k-1}+nr_{k-2}\)
\(d=m_{1}r_{k-2}+n_{1}r_{k-3}\)
当我们将这两个式子一直像上面的做法一样一直搞下去,就可以得到(学长说就是一个不断递归的过程,自己手模一下可能会好理解一些):
\(d=m_{2}r_{k-3}+n_{2}r_{k-4}\)
\(d=m_{3}r_{k-4}+n_{3}r_{k-5}\)
\(......\)
\(d=m_{k}a+n_{k}b\)
显然 \(m_{k}\) 和 \(n_{k}\) 一定是整数,故,\(ax+by=d\) 一定有整数解。
于是就有一个很重要的推论:
对于方程 \(ax+by=1\),只有当 \(a\),\(b\) 互质时,方程才有整数解。
有了上面的证明,这个就很容易证(本来不打算写证明了但万一有人看呢)。
证明:
设 \(a\),\(b\) 不互质,那么 \(a\),\(b\) 可以表示成 \(a=q\times \gcd(a,b)\),\(b=p\times \gcd(a,b)\),带入上面的式子,得到:
\(q \times \gcd(a,b) \times x + p\times \gcd(a,b)\times y=1\)
两边同时除以 \(\gcd(a,b)\),得到:
\(qx+py=\frac{1}{\gcd(a,b)}\)
显然,如果此时 \(a\),\(b\) 不互质,那么等式的右边已经成为了一个小数,那么,该方程一定不存在整数解。
故只有当整数 \(a\),\(b\) 互质时,该方程才会有整数解。
然后,判断二元不定方程是否有整数解的方法出现了:
对于方程 \(ax+by=z\),只有满足 \(\gcd(a,b)\mid z\),方程才有整数解。
证明(吐了):
设 \(d=\gcd(a,b)\),\(z=d\times q\)。
对于方程 \(ax+by=d\),我们设有一组解为 \(x_{1}\),\(y_{1}\),那么就有:
\(ax_{1}+by_{1}=d\)
两边同时乘上 \(p\),得到:
\(ax_{1}\times q+by_{1}\times q=d\times q\)
因为 \(z=d\times q\)
所以方程 \(ax+by=z\),一定存在一组整数解为 \(x=x_{1}\times q\),\(y=y_{1}\times q\)。
然后这东西还可以扩展到 \(n\) 元不定方程上。
对于不定方程 \(a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+...+a_{n}x_{n}=z\),满足 \(\gcd(a_{1},a_{2},...,a_{n})\mid z\) 时,方程才有整数解。
对于不定方程 \(a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+...+a_{n}x_{n}=1\),只有所有系数 \(a_{1},a_{2},...,a_{n}\) 的最大公约数为 \(1\) 时,方程才会有解。
所有系数 \(a_{1},a_{2},...,a_{n}\) 的最大公约数为 \(1\) 的充要条件是:满足不定方程 \(a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+...+a_{n}x_{n}=1\)。
终于结束了(上面的证明自己推一下就好啦)。
欧拉定理推论
若正整数 \(a\),\(n\) 互质,那么对于任意正整数 \(b\),有 \(a^{b}\equiv a^{b\bmod \varphi(n)}\pmod{n}\)
证明(跟费马小定理差不多好像):
把上面那个式子变一下形:\(a^{b-b\bmod \varphi(n)}\times a^{b\bmod \varphi(n)}\equiv a^{b\bmod \varphi(n)}\pmod{n}\)(这式子真他妈难打),所以接下来只需要证明 \(a^{b-b\bmod \varphi(n)}\equiv 1\pmod{n}\),又因为:\((b-b\bmod \varphi(n))\mid \varphi(n)\),设 \((b-b\bmod \varphi(n))=q\times \varphi(n)\)(\(q\) 为自然数),则有 \(a^{q\times \varphi(n)}=(a^{q})^{\varphi(n)}\),因为 \(a\),\(n\),互质,那么 \((a^{q})\) 与 \(n\) 也互质,那么就转化到了欧拉定理:\((a^{q})^{\varphi(n)}\equiv 1\pmod{n}\),成立,故得证。
这个推论可以帮助我们在求幂运算的时候缩小数据范围和计算次数。具体的说:在求乘方运算时,可以先把底数对 \(mod\) 取模,再把指数对 \(b\bmod \varphi(n)\) 取模。
特别的,如果 \(a\),\(mod\) 不互质,且 \(b>\varphi(n)\) 时,\(a^{b}\equiv a^{b\bmod \varphi(n)+\varphi(n)}\pmod{n}\)。
计算欧拉函数
来说一下如何计算欧拉函数的值,因为做模板题被 T 痛了。
参考:自为风月马前卒
第一种方法就是直接暴力循环枚举小于等于 \(n\) 的每一个数,然后用 \(gcd\) 函数来判断是否互质,很好写,很简单,很暴力,很 TLE。
第二种方法:大约是 \(\sqrt{n}\) 的复杂度(我不懂这个,我只在乎他会不会 T)。我们需要分情况讨论。
当 \(n=1\) 时,很明显是1。
当 \(n\) 为质数时,很明显是 \(n-1\),因为只有他自己与他不互质。
当 \(n\) 为合数的情况。
这个最难搞,先对 \(n\) 进行质因数分解。
设 \(n=a_{1}^{p_{1}}\times a_{2}^{p_{2}}...a_{k}^{p_{k}}\)
假设 \(k=1\)
辣么 \(\varphi(p_{k})=p^{k}-p^{k-1}\).
证明:
与一个数互素的数的个数就是这个数减去与他不互素的数的个数,因为 \(p\) 是素数,所以 \(p^{k}\) 中与其不互素的数为 \(p,2p...p^{k-1}p\),有 \(p^{k-1}\) 个,得证。
当 \(k\ne 1\) 时。
\(\varphi(n)=\varphi(a_{1}^{p_{1}}\times a_{2}^{p_{2}}...a_{k}^{p_{k}})\)
\(\varphi(n)=\prod_{i=1}^{k}a^{p_{i}}-a_{i}^{p_{i-1}}\)
\(\varphi(n)=\prod_{i=1}^{k}a_{i}^{p_{i}}(1-\frac{1}{p_{i}})\)
\(\varphi(n)=n\times \prod_{i=1}^{k}(1-\frac{1}{p_{i}})\)
好的把 dalao 的代码放在下面:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e7 + 10;
int p, ans = 1, N;
void GetPhi() {
for(int i = 2; i * i <= p; i++) {
if(p % i == 0) {
int now = i - 1; p /= i;
while(p % i == 0) now = now * i, p /= i;
ans = ans * now;
}
}
if(p != 1) ans *= (p - 1);
}
int main() {
cin >> p; N = p;
GetPhi();
cout << ans;
return 0;
}
第三种方法:线性筛。
因为欧拉函数是积性函数,因此可以用线性筛。
性质1:若 \(p\) 为素数,\(\varphi(n)=n-1\).
性质2:若 \(i \bmod p\ne 0\),且 \(p\) 为素数
则 \(\varphi(i\times p)=\varphi(i)\times \varphi(p)=\varphi(i\times p)=\varphi(i)\times (p-1)\)
这一步同时利用了性质1和欧拉函数的积性。
性质3:若 \(i\bmod p=0\),且 \(p\) 为素数
则 \(\varphi(i\times p)=\varphi(i)\times p\)
证明就算了吧咕咕咕。
dalao 代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
void GetPhi(int N) {
static int phi[MAXN], vis[MAXN], prime[MAXN], tot = 0;
for(int i = 2; i <= N; i++) {
if(!vis[i]) prime[++tot] = i, phi[i] = i - 1;
for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
vis[i * prime[j]] = 1;
if(!(i % prime[j])) {phi[i * prime[j]] = phi[i] * prime[j]; break;}
else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
while(cin >> N) cout << phi[N] << endl;
}
int main() {
GetPhi(100);
return 0;
}
因为我太蒻了,所以没有分析,以后在来填咕咕咕。
代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a,m,b;
inline int read(int m)//m是要模的数字,读入
{
int x=0,f=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch))//只要输入的是阿拉伯数字
{
x=x*10+ch-'0';//计算累加
if(x>=m) f=1;//f计算是否超过模数
x%=m;//取模不然会炸
ch=getchar();//继续读入
}
return x+(f==1?m:0);//最后看是否超过m如超过就加一个m防止后面计算出误
}
inline int ksm(int a,int b)//快速幂函数
{
int ans=1;
while(b!=0)
{
if(b%2==1)
ans=ans*a%m;
a=a*a%m;
b=b>>1;
}
return ans;
}
inline int phi(int n)//计算有多少个与n互质的数字
{
int ans=n,o=sqrt(n);//o为根号n
for(int i=2;i<=o;i++)//从2开始枚举到o
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1)ans=ans/n*(n-1);
return ans;
}
signed main()
{
cin>>a>>m;
b=read(phi(m));//输入b
cout<<ksm(a,b)<<endl;//计算
return 0;
}//by wwwaax
本文来自博客园,作者:北烛青澜,转载请注明原文链接:https://www.cnblogs.com/Multitree/p/16744312.html
The heart is higher than the sky, and life is thinner than paper.