Exponial(数论+Euler降幂+快速幂+递归)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这道题题意很简单就是求这个东西:
在这里插入图片描述
其实我觉得最不安逸的就是题读懂了,写不来,眼睁睁的看着别人AC,唉。。。。。。
不论怎么说,我感觉还是知道了欧拉降幂这个知识点,以前我只知道快速幂,矩阵快速幂,今天还遇见了欧拉快速幂,真的佩服前人的智慧;
我前面写过一个简单的2阶的幂,也是用的欧拉降幂,但是这个题好像更复杂一些;因为涉及到递归问题;
说实话欧拉降幂我只是记得到结论,但是这个题至于为什么没有判断幂和phi§的大小就直接递归了?也是结论?
首先还是来复习一个欧拉降幂结论吧:
在这里插入图片描述
因为打表可以直接知道1,2,3,4这些是不满足第三个的;所以可以直接算出这些值;然后>4的时候都用第三种情况来递归;至于为什么我猜这是结论吗?
我可以把在这里插入图片描述简写为e(n),那么可以知道这个东东:
在这里插入图片描述
所以我可以发现其实这个递归的时候只有m和n在变;所以我只需要递归m,n就行,但是递归结束条件是什么?
这里可以这样理解如果m一开始就进来为1;那么答案直接就是0了不是吗?所以递归结束条件为m==1;return 0;
所以根据这个东东我就可以写递归了;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//欧拉函数:求[1,n)与n互质的个数:
ll Euler(ll n)
{//模板
    ll res = n , a = n;
    for(ll i = 2 ; i*i <= a ; i++)
    {
        if(a % i == 0)  //i一定是素数
        {
            res = res / i * (i - 1);  //根据公式
            while(a % i == 0)  //把相同的除数排除
            {
                a /= i;
            }
        }
    }
    if(a > 1)  //最后只剩下 小于4的素数  或者n本身就是素数
        res = res / a *(a - 1);
    return res;
}
ll QP(ll x,ll n,ll Mod){
	   ll res=1;
	   while(n){
	   	  if(n&1){
	   	  	  res=(res*x)%Mod;
			 }
			 x=(x*x)%Mod;
			 n>>=1;
	   }
	   return res;
}
ll Euler_quick_power(ll n,ll m){//递归
	if(m==1)return 0;
	int t=Euler(m);//因为递归的时候m和上一个m是上面分析的关系
	return QP(n,Euler_quick_power(n-1,t)+t,m);//这里就是返回e(n)的值;
}
int main(){
	  ll n,m;
	scanf("%lld %lld",&n,&m);
	  	if(n==1)printf("%lld\n",1%m);//这几个特列都可以手算出来,因为很小
		else if(n==2)printf("%lld\n",2%m);
		else if(n==3)printf("%lld\n",9%m);
		else if(n==4)printf("%lld\n",(1<<18)%m);
	  	else  printf("%lld\n",Euler_quick_power(n,m));
   
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值