【洛谷P5091】【模板】欧拉定理【扩展欧拉定理】

题目大意:

题目链接:https://www.luogu.org/problem/P5091
a b m o d    m a^b\mod m abmodm


思路:

扩展欧拉定理的模板题。
具体还不会证明。证明就出门右转题解区吧。
欧拉定理:对于任意的 a , p ∈ Z ∗ a,p\in \Z^* a,pZ,若满足 ( a , b ) = 1 (a,b)=1 (a,b)=1,那么必然就有 a φ ( m ) ≡ 1 ( m o d   p ) a^{\varphi(m)} \equiv 1(mod\ p) aφ(m)1(mod p)
扩展欧拉定理:当 p ≥ φ ( m ) p\geq \varphi(m) pφ(m)时,必有
a p ≡ a p   m o d   φ ( m ) + φ ( m ) ( m o d   p ) a^p\equiv a^{p\ mod\ \varphi(m)+\varphi(m)}(mod\ p) apap mod φ(m)+φ(m)(mod p)
所以就算出 φ ( p ) \varphi(p) φ(p),然后从高位到低位依次读入 b b b的每一位,同时取模 φ ( m ) \varphi(m) φ(m)。然后由于最终的指数不会超过 1 0 6 10^6 106,所以直接暴力乘上去就可以了。
注意只有在 b > φ ( m ) b>\varphi(m) b>φ(m)时指数才需要在最后加 φ ( m ) \varphi(m) φ(m)


代码:

#include 
using namespace std;
typedef long long ll;

ll a,b,p,q,phi;
bool flag;

int main()
{
	scanf("%lld%lld",&a,&p);
	phi=q=p;
	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);
	while (scanf("%1lld",&q)==1)
	{
		b=b*10+q;
		if (b>=phi) flag=1;
		b%=phi;
	}
	if (flag) b+=phi;
	for (ll i=1,x=a;i<b;i++)
		a=a*x%p;
	printf("%lld\n",a);
	return 0;
} 

你可能感兴趣的:(数论,数学,洛谷模板题)