$$求證a^b\equiv a^{b\%\varphi(m)+\varphi(m)}(\%m),其中b\geq \varphi(m)$$
我們模$m$最多只有$m$種結果,所以根據鴿巢原理,在
$$a^0,a^1,...,a^m(\%m)$$
這$m+1$個數中,一定存在最小的$r$和最小的$s$,滿足$a^r\equiv a^{r+s}(\%m)$且$r+s\leq m.$$......(1)$
所以序列其實是這樣的:
$$a^0,a^1,a^2,...,a^{r-1},a^r,a^{r+1},...,a^{r+s-1},a^r,a^{r+1},...(\%m)$$
也就是說,從$a^0$到$a^{r-1}$不是重復的,但是從$a^r$開始,會循環出現$a^r,a^{r+1},...,a^{r+s-1}$,循環節長度為$s$$......(2)$
由$(1)$式得:$m|a^{r+s}-a^{r}$,即$m|a^{r}(a^{s}-1)$
不妨設$m=a^{r0}m'$,且$(a,m')=1$$......(3)$
變成$a^{r0}m'|a^{r}(a^{s}-1)$$......(4)$
不妨設$r0<r$
則由$(4)$式得$m'|a^{r-r0}(a^{s}-1)$,即$m'|a^{r-r0+s}-a^{r-r0}$,所以$a^{r-r0}\equiv a^{r-r0+s}(\%m')$
又因為$m'|m$,所以$a^{r-r0}\equiv a^{r-r0+s}(\%m)$,所以$r-r0$也滿足條件,這與$r$的最小性矛盾,所以$r0=r$,$m=a^rm'$
另一方面,在$(3)$式中,易知$(a,a^s-1)=1$,所以$(a^r,a^s-1)=1$
故$m'|a^{s}-1$,$a^s\equiv 1(\%m')$
因為$(a,m’)=1$,根據歐拉定理得$a^{\varphi (m')}\equiv 1(\% m')$
所以$s|\varphi (m')$
又因為$m=a^{r}m'$,$(a,m')=1$,所以$\varphi(m')|\varphi(m)$
所以$s|\varphi (m)$
所以結論$(2)$可描述為:
$$a^0,a^1,a^2,...,a^{r-1},a^r,a^{r+1},...,a^{r+\varphi (m)-1},a^r,a^{r+1},...(\%m)$$
從$a^0$到$a^{r-1}$不是重復的,但是從$a^r$開始,會循環出現$a^r,a^{r+1},...,a^{r+\varphi (m)-1}$,循環節長度為$\varphi (m)$$......(5)$
因為$m=a^rm'$,所以$\varphi(m)\geq \varphi(a^r)\geq a^{r-1}(a-1)\geq r$
所以結論$(5)$又可以描述為:從$a^0$到$a^{\varphi(m)-1}$不是重復的,但是從$a^{\varphi(m)}$開始,會循環出現$a^\varphi(m),a^{\varphi(m)+1},...,a^{\varphi(m)+\varphi (m)-1}$,循環節長度為$\varphi (m)$$......(5)$
所以$$a^b\equiv a^{b\%\varphi(m)+\varphi(m)}(\%m),其中b\geq \varphi(m)$$
另外,如果$b < \varphi(m) $直接快速冪就可以了。
來看一道例題
題目描述
C同學竟然卡題了!而且還卡在一個不難的題目上。題目是這樣的:
定義a^b為a的b次方,並且^是滿足右結合的,即a^b^c^d=a^(b^(c^d))。例如,2^3^2=2^(3^2)=2^9=512。
現在給定n個數a1,a2,…,an,求a1 ^ a2 ^ … ^ an對p取模的值。
輸入格式
輸入包括多組數據。
第一行一個整數T,表示數據組數。
接下來每組數據第一行兩個整數n,p,第二行n個整數依次描述a1到an。n,p,ai的意義與題目描述一致。
輸出格式
對於每組數據輸出一行,包含一個整數,即a1 ^ a2 ^ … ^ an對p取模的值。
輸入樣例
2
5 13
2 2 2 2 2
3 9
2 3 2
輸出樣例
3
8
數據范圍
對於20%的數據,保證n=2;
對於另外30%的數據,保證n≤4,並且a1 ^ a2 ^ … ^ an的位數≤1000,數據組數<=5;
對於100%的數據,保證2≤n≤20,0<p,ai<10^7,數據組數≤100。
我們在求快速冪的時候看一下有沒有大於等於mod即可

#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>適用於CF,UOJ,但不適用於poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define fill(a,l,r,v) fill(a+l,a+r+1,v) #define re(i,a,b) for(i=(a);i<=(b);i++) #define red(i,a,b) for(i=(a);i>=(b);i--) #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define p_b(a) push_back(a) #define SF scanf #define PF printf #define two(k) (1<<(k)) #define SIZE(x) (int(x.size()) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } const int maxn=25; int n,p,s; int a[maxn],b[maxn],c[maxn],d[maxn]; int mul(int x) { int i,res=x; for(i=2;i*i<=x;i++) if(x%i==0) { while(x%i==0)x/=i; res=res/i*(i-1); } if(x>1)res=res/x*(x-1); return res; } int getpow(int a,int k,int modd) { LL res=1,x=a,flag=0; for(;k;k>>=1) { if(k&1) { if(res*x>=modd) flag=1; res=res*x%modd; } if(k==1)break; if(x*x>=modd)flag=1; x=x*x%modd; } if(flag)res+=modd; return res; } int main() { freopen("pow.in","r",stdin); freopen("pow.out","w",stdout); int i,j,T=gint(); while(T--) { n=gint();p=gint();mmst(a,0);mmst(b,0);mmst(c,0);mmst(d,0); re(i,1,n)a[i]=gint(); s=0;for(int t=p;t!=1;t=mul(t))b[++s]=t; re(j,1,s) { c[j]=a[n]%b[j]; if(a[n]>=b[j])c[j]+=b[j]; } red(i,n-1,1) { re(j,1,s)d[j]=getpow(a[i],c[j+1],b[j]); re(j,1,s)c[j]=d[j]; } PF("%d\n",c[1]%p); } return 0; }