这道题题意很简单就是求这个东西:
其实我觉得最不安逸的就是题读懂了,写不来,眼睁睁的看着别人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;
}