扩展欧拉定理

扩展欧拉定理

前置芝士

欧拉定理

定义

对于a与m不一定互质的情况,有:

\[a^c~\equiv~\begin{cases}a^{c\mod\varphi(m)} &\gcd(a,m)~=~1 \\a^c &\gcd(a,m)~\neq~1~且~c~<~\varphi(m) \\ a^{c\mod\varphi(m)+\varphi(m)}&\gcd(a,m)~\not=~1~且~c~>=~\varphi(m)\end{cases} \]

推论

\(m=1\) 时明显成立,接下来讨论 \(m\not=1\) 的情况。

对于 \(\gcd(a,m)=1\) 的情况,因为 \(a^{\varphi(m)}\equiv 1\pmod m\) ,所以每 \(\varphi(m)\)\(a\) 就相当于乘 \(1\) 。于是只需要算

\(c\mod\varphi(m)\) 次。

对于 \(c<\varphi(m)\) 的情况,直接爆算

下面证明第三种情况。

先证明 \(a\) 是一个质数的情况:

引理1

\(\forall p\) 为质数,\(r\in Z^+\) ,都有 \(\varphi(p^r)=(p-1)\times p^{r-1}\)

证明:

由于p是一个质数,所以 \(1\sim (p^r-1)\) 中有且仅有 \(i\times p,i\in (0,p^{r-1})\)\(p^r\) 不互质。

于是 \(\varphi(p^r)=p^r-p^{r-1}=p^{r-1}\times (p-1)\)

证毕
引理2

\(\forall~k\in Z\)\(\exists~a,b,x,y\in Z^+,x^a\times y^b=k\) ,都有 \(a,b\leq\varphi(k)\)

证明

先考虑k为一个质数p的r次幂的情况。根据引理1有:

\[\varphi(k)=\varphi(p^r)=(p-1)\times p^{r-1} \]

下面说明 \((p-1)\times p^{r-1}\geq r\)

当p=2时:

经验证\(~r=1,2,3~\)时成立。当\(~r>3~\)时按照r的大小做数学归纳,可证正确性。

\(~p~>~2~\)时,不等号左侧增大,右侧不变,不等式仍然成立。

考虑k是多个质数幂时的情况,按照质数个数做数学归纳,正确性成立。

任意组合质数,引理得证。

证毕
引理三:

\(\exists~r~\leq~c~,a^{\varphi(m)+r}~\equiv~a^r\pmod m。\)

证明:

\(m=t\times a^r\) ,其中 \(\gcd(t,a)=1\) ,t的存在性显然

因为 \(\gcd(t,a)=1\) ,且 \(\varphi\) 函数是一个积性函数,所以 \(\varphi(t)|\varphi(m)\)

根据欧拉定理,\(a^{\varphi(t)}~\equiv~1~\pmod t\) ,于是:

\[a^{\varphi(m)}~\equiv~1~\pmod t \]

同余式同乘 \(a^r\) ,于是:

\[a^{\varphi(m)+r}~\equiv~a^r~\pmod m \]

已经证明可以构造出这样的r。根据引理2,\(r~\leq~\varphi(m)\)。又 \(c~\geq~\varphi(m)\),于是可证构造出的\(r~\leq~c\)。定理得证。

证毕

于是:

\[a^c~\equiv~a^{c-r+r}~\equiv~a^{c-r+\varphi(m)+r}~\equiv~a^{c+\varphi(m)}~\pmod m \]

对上式做数学归纳,可得\(a^c~\equiv~a^{c+k\varphi(m)}~,~k~\in~Z\),需保证指数为正。

于是最小的合法的指数即为\(c\mod\varphi(m)~+~\varphi(m)\)

于是有:

\[a^c~\equiv~a^{c~\mod~\varphi(m)~+~\varphi(m)}\pmod m \]

当a是一个质数的幂次时,设 \(a=p^k\) ,则

\[a^c\equiv p^{ck}\equiv p^{ck+\varphi(m)}\equiv p^{ck+k\varphi(m)}\equiv (p^k)^{c+\varphi(m)}\equiv (p^k)^{c\mod\varphi(m)+\varphi(m)} \pmod m \]

当a时多个质数次幂的乘积时,依据唯一分解定理做数学归纳,即证正确性。证毕。

代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a,m,b;

inline ll read(ll m){
	register ll 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;
		x%=m;ch=getchar();
	}
	return x+(f==1?m:0);
}

ll phi(ll n){
	ll ans=n,m=sqrt(n);
	for(ll i=2;i<=m;i++){
		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;
}

ll fast_pow(ll a,ll b,ll p){
	ll ret=1;
	for(;b;b>>=1,a=a*a%p)
		if(b&1) ret=ret*a%p;
	return ret;
}

int main()
{
    scanf("%lld%lld",&a,&m);
    b=read(phi(m));
    printf("%lld\n",fast_pow(a,b,m));
    return 0;
}

例题

CF17D Notepad

思路

这道题的范围是 \(2\leq a\leq 10^{1000,000}\)\(1\leq n\leq 10^{1000,000}\)\(1\leq p\leq 10^9\)

一个\(a\)进制的数字的每一位有\(a\)种取值,但是题目要求不能有前导0,所以第一位只有\(a-1\)种取值。

所以满足要求的\(a\)进制数有 \((a-1)a^{n-1}\) 个。

所以题目要求我们求得就是

\[(a-1)a^{n-1}\mod p \]

(但是当 \(p|(a-1)a^{n-1}\) 时应输出 \(p\) 。因为此时最后一页有0个字,相当于这一页还没写,也就不是最后一页了)

\(a,n\) 很大,但是 \(p\leq 10^9\) 。根据扩展欧拉定理,有 \(a^{n-1}\equiv a^{(n-1)\mod\varphi(p)+\varphi(p)} \pmod p\) 。所以我们可以边读入边取模。反正 \(ab\mod p\equiv(a\mod p)\times (b\mod p)~\mod p\)

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;

const int N=1000010;
char sa[N],sn[N];
ll p,a,n,phi,q,ans;
int len1,len2;
bool flag;

ll power(ll x,ll k)
{
	ll ans=1;
	for (;k;k>>=1,x=x*x%p)
		if (k&1) ans=ans*x%p;
	return ans;
}

int main()
{
	scanf("%s %s %lld",sa+1,sn+1,&p);
	phi=q=p; len1=strlen(sa+1); len2=strlen(sn+1);
	for (ll i=2;i*i<=q;i++)
		if (!(q%i))
		{
			phi=phi/i*(i-1);
			while (!(q%i)) q/=i;
		}
	if (q>1) phi=phi/q*(q-1);
	for (int i=1;i<=len1;i++)
		a=(a*10+sa[i]-48)%p;
	for (int i=len2;i>=1;i--)  //n-1
		if (sn[i]==48) sn[i]='9';
		else
		{
			sn[i]--;
			break;
		}
	for (int i=1;i<=len2;i++)
	{
		n=n*10+sn[i]-48;
 		if (n>=phi) flag=1;
		n%=phi;
	}
	if (flag) n+=phi;
	ans=((a-1)*power(a,n)%p+p)%p;
	if (ans) printf("%lld",ans);
		else printf("%lld",p);
	return 0;
}
posted @ 2020-07-25 17:02  jasony_sam  阅读(283)  评论(0编辑  收藏  举报