LG5901 【模板】歐拉定理
阿新 • • 發佈:2019-04-11
lin flag sam 說明 輸出 its cpp 分析 math
。
題意
題目描述
給你三個正整數,$a,m,b$,你需要求:
$a^b \mod m$
輸入輸出格式
輸入格式:一行三個整數,$a,m,b$
輸出格式:一個整數表示答案
輸入輸出樣例
輸入樣例#1: 復制2 7 4輸出樣例#1: 復制
2輸入樣例#2: 復制
998244353 12345 98765472103312450233333333333輸出樣例#2: 復制
5333
說明
註意輸入格式,$a,m,b$ 依次代表的是底數、模數和次數
樣例1解釋:
$2^4 \mod 7 = 2$
輸出2
數據範圍:
對於全部數據:
$1≤a≤10^9$
$1≤b≤10^{20000000}$
$1≤m≤10^6$
分析
費馬小定理
當 \(a,p\in \mathbb{Z}\) 且 \(p\) 為質數,且 \(a\not\equiv 0\pmod{p}\) 時有:
\(a^{p-1}\equiv 1\pmod{p}\) 。
所以 \(a^b\equiv a^{b\bmod (p-1)}\pmod p\) 。
歐拉定理
當 \(a,m\in \mathbb{Z}\) ,且 \(\gcd(a,m)=1\) 時有:
\(a^{\varphi(m)}\equiv 1\pmod{m}\) 。
這裏 \(\varphi(x)\) 是數論中的歐拉函數。
所以 \(a^b\equiv a^{b\bmod \varphi(m)}\pmod m\)
擴展歐拉定理
當 \(a,m\in \mathbb{Z}\) 時有:
\(a^b\equiv\left\{\begin{matrix}a^b&,b<\varphi(m)\\a^{b\bmod\varphi(m)+\varphi(m)}&,b\ge\varphi(m)\end{matrix}\right.\pmod m\) 。
對於那個高精度整數,一邊乘10相加,一遍取模即可。時間復雜度\(O(\sqrt m+\lg b+\log_2 m)\)
代碼
#include<bits/stdc++.h> #define rg register #define il inline #define co const template<class T>il T read(){ rg T data=0,w=1;rg char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();} while(isdigit(ch)) data=data*10+ch-'0',ch=getchar(); return data*w; } template<class T>il T read(rg T&x) {return x=read<T>();} typedef long long ll; int main(){ int a=read<int>(),m=read<int>(); int phi=m,mm=m; for(int i=2;i*i<=mm;++i)if(mm%i==0){ phi=phi/i*(i-1); while(mm%i==0) mm/=i; } if(mm>1) phi=phi/mm*(mm-1); int b=0,flag=0; char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)){ b=b*10+ch-'0',ch=getchar(); if(b>=phi) b%=phi,flag=1; } if(b>=phi) b%=phi,flag=1; if(flag) b+=phi; int ans=1; for(;b;b>>=1,a=(ll)a*a%m) if(b&1) ans=(ll)ans*a%m; printf("%d\n",ans); return 0; }
LG5901 【模板】歐拉定理