B.super_log (欧拉降幂)

•题意

定一个一个运算log*,迭代表达式为

The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛

给定一个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的互素处理

具体证明请看这里

 •代码

 1 #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 }
View Code

相关文章: