B.super_log (欧拉降幂)
•题意
定一个一个运算log*,迭代表达式为
给定一个a,b计算直到迭代结果>=b时,最小的x,输出对m取余后的值
•思路
$log*_{a}(1)=1+log*_{a}(0)=1-1=0$
$log*_{a}(a)=1+log*_{a}(log_{a}(a))=1+log*_{a}(1)=1$
$log*_{a}(a^{a})=1+log*_{a}(a)=2$
....
以此类推得$log*_{a}(a^{a^{a^{a^{a^{...}}}}})=b$ (共b个a)
接下来接转化为$a^{a^{a^{a^{a^{...}}}}}$ (共b个a) 对m取模得结果
ps.如果对欧拉降幂不熟悉的话可以先看一下这个题(戳我~)
利用欧拉降幂
$a^{b}=\begin{cases}a^{b\%\varphi(p)} \ \ \ \ \ \ \ \ \ \ gcd(a,p)=1 \\ a^{b} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gcd(a,p)\neq 1,b \leqslant \varphi(p)\\a^{b\%\varphi(p)+\varphi(p)} \ \ gcd(a,p)\neq1,b\geqslant \varphi(p) \\ \end{cases}$
递归求解,至多走到2log层模数就会变成1,返回答案就行了。
但是在求$a^{a}\%\varphi(p)$时怎么计算$a$和$\varphi(p)$的大小呢
利用取模方法!
在取模时,如果大于$\varphi(p)$就取模 x=x%mod,否则不取模x=x,就可以当作a和p的互素处理
具体证明请看这里
•代码
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 ll qpow(ll a,ll b,ll mod)//快速幂 5 { 6 ll res=1; 7 while(b) 8 { 9 if(b&1) 10 res=res*a>mod?res*a%mod+mod:res*a; 11 a=a*a>mod?a*a%mod+mod:a*a; 12 b>>=1; 13 } 14 return res; 15 } 16 17 ll phi(ll x)//求x的欧拉函数值 18 { 19 ll res=x; 20 for(int i=2;i*i<=x;i++) 21 { 22 if(x%i==0) 23 { 24 while(x%i==0) 25 x/=i; 26 res=res-res/i; 27 } 28 } 29 if(x>1) 30 res=res-res/x; 31 return res; 32 } 33 34 ll solve(ll a,ll b,ll m) 35 { 36 if(m == 1) 37 return 0; 38 if(b==0||a==1) 39 return 1ll; 40 41 ll p=phi(m); 42 return qpow(a,solve(a,b-1,p),m); 43 } 44 45 int main() 46 { 47 int t; 48 cin>>t; 49 while(t--) 50 { 51 ll a,b,m; 52 cin>>a>>b>>m; 53 cout<<solve(a,b,m)%m<<endl; 54 } 55 }