欧拉定理及扩展

欧拉定理:对于任意互素的a和n,有 a φ ( n ) 1 ( m o d n ) a^{\varphi(n)}\equiv1(mod n)
证明:
记小于n且与n互素的数为 R = { x 1 , x 2 . . . x φ ( n ) x_1,x_2...x_\varphi(n) }
令S = { a x 1 % n , a x 2 % n , , a x φ ( n ) % n } \{ax_1\%n,ax_2\%n,\cdots,ax_{\varphi(n)}\%n\}

i [ 1 , φ ( n ) ] \forall i\in[1,\varphi(n)]
( a , n ) = 1 , ( x i , n ) = 1 \because (a,n)=1,(x_i,n)=1
( a x i , n ) = 1 \therefore (ax_i,n)=1
( a x i % n , n ) = 1 由最大公约数的性质可得(ax_i\%n,n)=1
S n n 所以 S 中所有元素都与 n 互质,且都小于 n。

x 1 % n = x 1 , x 2 % n = x 2 , , a % n \because x_1\%n = x_1,x_2\%n = x_2,\cdots,且a\%n为定值
S \therefore S 中无重复元素
S = R \therefore S=R

i = 1 φ ( n ) a x i % n = i = 1 φ ( n ) x i \therefore\prod_{i=1}^{\varphi(n)}ax_i\%n=\prod_{i=1}^{\varphi(n)}x_i
i = 1 φ ( n ) a x i i = 1 φ ( n ) x i ( m o d    n ) \therefore\prod_{i=1}^{\varphi(n)}ax_i\equiv\prod_{i=1}^{\varphi(n)}x_i(\mod n)\Longrightarrow a φ ( n ) i = 1 φ ( n ) x i i = 1 φ ( n ) x i ( m o d    n ) a^{\varphi(n)}\prod_{i=1}^{\varphi(n)}x_i\equiv\prod_{i=1}^{\varphi(n)}x_i(\mod n)
( i = 1 φ ( n ) x i , n ) = 1 又(\prod_{i=1}^{\varphi(n)}x_i,n)=1
a φ ( n ) 1 ( m o d    n ) 故a^{\varphi(n)}\equiv1(\mod n)

扩展欧拉定理(也是常说的欧拉降幂)
对于任意的a,b,m, b > = φ ( m ) 若b >=\varphi(m) a b a b m o d    φ ( m ) + φ ( m ) ( m o d   m ) a^b \equiv a^{b \mod \varphi(m) + \varphi(m)}(mod\ m)

求a ^ a ^ a ^ a ^ … ^ a % c,一共b个a

#include <cstdio>
typedef long long ll;

ll euler(ll n)    //计算模数的欧拉函数 
{
	ll res = n,a = n;
	for (int i = 2; i * i <= n; i++)
	{
		if( a % i == 0 )
		{
			res -= res / i;
			while( a % i == 0 ) a /= i;
		}
	}
	if( a > 1 ) res -= res / a;
	return res;
}

ll q_pow(ll a,ll b,ll mod)    //快速幂 
{
	ll ans = 1;
	int flag = 0;
	while( b )
	{
		if( b & 1 ) 
		{
			ans *= a;
			if( ans > mod ) flag = 1;
			ans %= mod;
		}
		a *= a;
		if( a > mod ) flag = 1;
		a %= mod;
		b >>= 1;
	}
	return ans + flag * mod;   
	//不能简单的返回%mod的值,大于mod时要加mod(欧拉定理的约束) 
}

ll cal(ll a,ll l,ll r,ll mod)
{
	if( mod == 1 ) return 1;   //模数为1时直接返回1回溯,因为后面等于多少到这一层%1都等于0 
	if( l == r )      //递归到最后,回溯 
	{
		if( a > mod ) a = a % mod + mod;
		return a;
	}
	ll b = cal(a,l+1,r,euler(mod));  //计算下一层的指数(注意模数变为当前值的欧拉值) 
	return q_pow(a,b,mod);    //快速幂计算 
}

int main()
{
	int t;
	scanf("%d",&t);
	while( t-- )
	{
		ll a,b,c;
		ll ans;
		scanf("%lld%lld%lld",&a,&b,&c);
		if( b == 0 ) ans = 1;
		else if( b == 1 ) ans = a;
		else ans = cal(a,1,b,c);
		ans %= c;
		printf("%lld\n",ans);
	}
	return 0;
} 
发布了103 篇原创文章 · 获赞 6 · 访问量 7036

猜你喜欢

转载自blog.csdn.net/weixin_44316314/article/details/99606297