【数论】欧拉定理 扩展欧拉定理
文章目录
- 前置知识
- 一、欧拉定理
- 1. 欧拉定理的内容
- 2.欧拉定理的证明
- 二、扩展欧拉定理
- 1. 扩展欧拉定理的内容
- 2. 扩展欧拉定理的证明
- 3. 应用:欧拉降幂
- 4. 【模板】扩展欧拉定理 ⭐⭐⭐⭐
- 三、练习:上帝与集合的正确用法 ⭐⭐⭐⭐
- 1. 解题思路
- 2. 代码实现
前置知识
- 欧拉函数
一、欧拉定理
1. 欧拉定理的内容
欧拉定理:若 a , n a,n a,n 均为正整数,且 gcd ( a , n ) = 1 \gcd(a,n)=1 gcd(a,n)=1,则
a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi(n)}\equiv1\pmod n aφ(n)≡1(modn)
如果你知道费马小定理,那么这个欧拉定理你一定觉得很眼熟。费马小定理:
a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap−1≡1(modp)
其中 p p p 是素数,又根据我们欧拉函数的性质可知, φ ( p ) = p − 1 \varphi(p) = p - 1 φ(p)=p−1,所以费马小定理实际上就是欧拉定理的一种特殊情况。
2.欧拉定理的证明
证:设小于 n n n 且与 n n n 互素的所有正整数构成一个集合 Z n = { x 1 , x 2 , ⋯ x φ ( n ) } \Z_n=\{x_1,x_2,\cdots x_{\varphi(n)}\} Zn={x1,x2,⋯xφ(n)},共 φ ( n ) \varphi(n) φ(n) 个元素。
现在,我将把 Z n \Z_n Zn 中的每个元素进行一个运算得到另一个值 m m m:
a x 1 m o d n = m 1 a x 2 m o d n = m 2 ⋮ a x φ ( n ) m o d n = m φ ( n ) ax_1\bmod n=m_1\\ ax_2\bmod n=m_2\\ \vdots\\ ax_{\varphi(n)}\bmod n=m_{\varphi(n)} ax1modn=m1ax2modn=m2⋮axφ(n)modn=mφ(n)
知道 m m m 是怎么来的之后,现在我把这所有的 m m m 组成一个新的集合 S = { m 1 , m 2 , ⋯ m φ ( x ) } S=\{m_1,m_2,\cdots m_{\varphi(x)}\} S={m1,m2,⋯mφ(x)},共 φ ( n ) \varphi(n) φ(n) 个元素。
现在我说 Z n = S \Z_n=S Zn=S 你信吗?不妨来证明一下:
由最开始的条件可知, a a a 与 n n n 互素,集合 Z n \Z_n Zn 中的任意一个元素 x i x_i xi 也与 n n n 互素。那么易知它们的乘积 a x i ax_i axi 同样也与 n n n 互素。这是因为 a a a 和 x i x_i xi 都无法拆分出一个 n n n 的约数,那它们的乘积当然也就拆不出这么一个数,因此互素。又因为 m m m 的值是通过 a x i ax_i axi 模 n n n 得到的,这么做并不会改变数与模数之间的最大公约数,所以可以推出 m m m 与 n n n 互素。
简而言之就是
( a , n ) = 1 , ( x i , n ) = 1 ⇒ ( a x i , n ) = 1 ⇒ ( m i , n ) = 1 (1) (a,n)=1,(x_i,n)=1\ \Rightarrow\ (ax_i,n)=1\ \Rightarrow \ (m_i,n)=1\tag1 (a,n)=1,(xi,n)=1 ⇒ (axi,n)=1 ⇒ (mi,n)=1(1)
又由于 Z n \Z_n Zn 中的元素介于 n n n 之间,任意两个元素之间互不相等,于是无论它们模 n n n 还是乘以 a a a 之后模 n n n,都是不相等的:
x i ≠ x j ⇒ ( x i m o d n ) ≠ ( x j m o d n ) ⇒ ( a x i m o d n ) ≠ ( a x j m o d n ) ⇓ m i ≠ m j (2) x_i\ne x_j\ \ \Rightarrow\ \ (x_i\bmod n)\ne (x_j\bmod n)\ \ \Rightarrow\ \ (ax_i\bmod n)\ne (a x_j\bmod n)\\ \Downarrow\\ m_i\ne m_j\tag2 xi=xj ⇒ (ximodn)=(xjmodn) ⇒ (aximodn)=(axjmodn)⇓mi=mj(2)
因此,上面的(1)和(2)式就说明了一件事情:集合 S S S 中的元素与 n n n 互素且与互不相等。那我们都知道,这样的集合肯定是唯一确定的,那这不就是集合 Z n \Z_n Zn 吗?因此我们得出了 一个很重要的结论:
Z n = S \Z_n=S Zn=S
于是这两个集合内的每个元素相乘最后的结果肯定相等,即
∏ n = 1 φ ( n ) x i = ∏ n = 1 φ ( n ) m i \prod_{n=1}^{\varphi(n)}x_i=\prod_{n=1}^{\varphi(n)}m_i n=1∏φ(n)xi=n=1∏φ(n)mi
因此它们模 n n n 之后也相等,即
∏ n = 1 φ ( n ) x i m o d n = ∏ n = 1 φ ( n ) m i m o d n \prod_{n=1}^{\varphi(n)}x_i\bmod n=\prod_{n=1}^{\varphi(n)}m_i\bmod n n=1∏φ(n)ximodn=n=1∏φ(n)mimodn
我们对这个这个等式做进一步分析
∏ n = 1 φ ( n ) x i m o d n = ∏ n = 1 φ ( n ) m i m o d n = ( m 1 ⋅ m 2 ⋅ ⋯ m φ ( n ) ) m o d n = [ ( a x 1 m o d n ) ⋯ ( a x φ ( n ) m o d n ) ] m o d n \begin{aligned}\prod_{n=1}^{\varphi(n)}x_i\bmod n&=\prod_{n=1}^{\varphi(n)}m_i\bmod n\\ &=(m_1\cdot m_2\cdot\cdots m_{\varphi(n)})\bmod n\\ &=[(ax_1\bmod n)\cdots(ax_{\varphi(n)}\bmod n)]\bmod n\end{aligned} n=1∏φ(n)ximodn=n=1∏φ(n)mimodn=(m1⋅m2⋅⋯mφ(n))modn=[(ax1modn)⋯(axφ(n)modn)]modn
由模运算的性质可知,该等式可以进一步转化为
= ( a x 1 ⋅ a x 2 ⋅ ⋯ a x φ ( n ) ) m o d n =(ax_1\cdot ax_2\cdot\cdots ax_{\varphi(n)})\bmod n =(ax1⋅ax2⋅⋯axφ(n))modn
将所有的 a a a 合并,即
= ( a φ ( n ) ⋅ x 1 ⋅ x 2 ⋯ x φ ( n ) ) m o d n = ( a φ ( n ) ∏ n = 1 φ ( n ) x i ) m o d n \begin{aligned}&=(a^{\varphi(n)}\cdot x_1\cdot x_2\cdots x_{\varphi(n)})\bmod n\\ &=(a^{\varphi(n)}\prod_{n=1}^{\varphi(n)}x_i)\bmod n\end{aligned} =(aφ(n)⋅x1⋅x2⋯xφ(n))modn=(aφ(n)n=1∏φ(n)xi)modn
做了一长串运算,最终得到了下面的等式
( a φ ( n ) ∏ n = 1 φ ( n ) x i ) m o d n = ∏ n = 1 φ ( n ) x i m o d n (a^{\varphi(n)}\prod_{n=1}^{\varphi(n)}x_i)\bmod n=\prod_{n=1}^{\varphi(n)}x_i\bmod n (aφ(n)n=1∏φ(n)xi)modn=n=1∏φ(n)ximodn
根据同余的性质,我们可以两边同时去除以 ∏ n = 1 φ ( n ) x i \prod_{n=1}^{\varphi(n)}x_i ∏n=1φ(n)xi,最终得到
a φ ( n ) m o d n = 1 m o d n ⇓ a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi(n)}\bmod n=1\bmod n\\ \Downarrow\\ a^{\varphi(n)}\equiv1\pmod n aφ(n)modn=1modn⇓aφ(n)≡1(modn)
欧拉定理,证毕!
二、扩展欧拉定理
欧拉定理也就看个乐呵,真正有用的还是扩展欧拉定理。
1. 扩展欧拉定理的内容
顾名思义,这是欧拉定理的拓展,也就是一般形式。
对于任意的正整数 a , b , n a,b,n a,b,n,若 b ≥ φ ( n ) b\geq\varphi(n) b≥φ(n) ,则有
a b ≡ a b m o d φ ( n ) + φ ( n ) ( m o d n ) ( b ≥ φ ( n ) ) a^b\equiv a^{b\bmod \varphi (n)+\varphi(n)}\pmod n\\ (b\geq\varphi(n)) ab≡abmodφ(n)+φ(n)(modn)(b≥φ(n))
如果 b ≥ φ ( n ) b\geq\varphi(n) b≥φ(n),那么直接就是 a b ≡ a b ( m o d n ) a^b\equiv a^b \pmod n ab≡ab(modn)。
2. 扩展欧拉定理的证明
- 引理 1:
a b ≡ a b m o d φ ( n ) ( m o d n ) a^b\equiv a^{b\bmod\varphi(n)}\pmod n ab≡abmodφ(n)(modn)
证:我们都知道欧拉定理,即当 gcd ( a , n ) = 1 \gcd(a,n)=1 gcd(a,n)=1,有
a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi(n)}\equiv1\pmod n aφ(n)≡1(modn)
现在不妨设 b = k φ ( n ) + t , t = b m o d φ ( n ) b=k\varphi(n)+t,t=b\bmod\varphi(n) b=kφ(n)+t,t=bmodφ(n),其中 k ∈ Z k\in \Z k∈Z。那么就有
a b m o d n = a k φ ( n ) + t m o d n = ( a φ ( n ) ) k ⋅ a t m o d n \begin{aligned}a^b\bmod n&=a^{k\varphi(n)+t}\bmod n\\ &=(a^{\varphi(n)})^k\cdot a^t\bmod n\end{aligned} abmodn=akφ(n)+tmodn=(aφ(n))k⋅atmodn
根据欧拉定理以及模运算的性质,可得
= 1 k ⋅ a t m o d n = a b m o d φ ( n ) m o d n \begin{aligned}&=1^k\cdot a^t\bmod n\\ &=a^{b\bmod\varphi(n)}\bmod n\end{aligned} =1k⋅atmodn=abmodφ(n)modn
综上,我们就得到了
a b m o d n = a b m o d φ ( n ) m o d n ⇓ a b ≡ a b m o d φ ( n ) ( m o d n ) a^b\bmod n=a^{b\bmod\varphi(n)}\bmod n\\ \Downarrow\\ a^b\equiv a^{b\bmod\varphi(n)}\pmod n abmodn=abmodφ(n)modn⇓ab≡abmodφ(n)(modn)
而这个式子,就是欧拉定理的推论,这里把它叫做引理 1。
- 引理 2:
若 p p p 是素数, q q q 是正整数且 q > 1 q>1 q>1,则
φ ( p q ) ≥ q \varphi(p^q)\geq q φ(pq)≥q
**证:**由前面提到的欧拉函数的性质可知
φ ( p q ) = p q − p q − 1 = p q − 1 ( p − 1 ) φ(p^q) = p^q - p^{q-1} = p^{q-1}(p - 1)\ φ(pq)=pq−pq−1=pq−1(p−1)
当 p , q p,q p,q 都为 2 2 2 时,易知 φ ( 4 ) = 2 ≥ 2 \varphi(4)=2\geq2 φ(4)=2≥2 没毛病;
当 p = 2 , q > 2 p=2,q>2 p=2,q>2 时, q q q 每增加 1 1 1,由上面的式子可知 φ ( p q ) φ(p^q) φ(pq) 是成倍成倍地增加,因此肯定不等式左边比右边增加快得多,因此成立;
当 q = 2 , p > 2 q=2,p>2 q=2,p>2 时, p p p 在增加的时候, φ ( p q ) φ(p^q) φ(pq) 自然也在增加,而不等式右边的值不变,因此同样成立。
- 扩展欧拉定理的证明
① 当 gcd ( a , n ) = 1 \gcd(a,n)=1 gcd(a,n)=1 时,由同余的性质
a φ ( n ) ≡ 1 ( m o d n ) , a b ≡ a b m o d φ ( n ) ( m o d n ) ⇓ a b ≡ a b m o d φ ( n ) + φ ( n ) ( m o d n ) a^{\varphi(n)}\equiv1\pmod n\ ,\ a^b\equiv a^{b\bmod\varphi(n)}\pmod n\\ \Downarrow\\ a^b\equiv a^{b\bmod \varphi (n)+\varphi(n)}\pmod n aφ(n)≡1(modn) , ab≡abmodφ(n)(modn)⇓ab≡abmodφ(n)+φ(n)(modn)
显然成立。
② 当 gcd ( a , n ) ≠ 1 \gcd(a,n)\ne1 gcd(a,n)=1 时,我们对 n n n 进行标准素因子分解,可得
n = p 1 q 1 p 2 q 2 ⋯ p s q s = ∏ i = 1 s p i q i n={p_1}^{q_1}{p_2}^{q_2}\cdots {p_s}^{q_s}=\prod_{i=1}^{s}p_i^{q_i} n=p1q1p2q2⋯psqs=i=1∏spiqi
这个时候我们只需要证明对于任意一个 p i q i p_i^{q_i} piqi,都有 a b ≡ a b m o d φ ( n ) + φ ( n ) ( m o d p i q i ) a^b\equiv a^{b\bmod \varphi (n)+\varphi(n)}\pmod{ p_i^{q_i}} ab≡abmodφ(n)+φ(n)(modpiqi) 成立即可。何以见得?因为根据同余的一个很重要的性质,若
x ≡ y ( m o d n 1 ) , x ≡ y ( m o d n 2 ) ⇓ x ≡ y ( m o d Lcm [ n 1 , n 2 ] ) x\equiv y\pmod {n_1},x\equiv y\pmod {n_2}\\ \Downarrow\\ x\equiv y\pmod {\operatorname {Lcm} [n_1,n_2]} x≡y(modn1),x≡y(modn2)⇓x≡y(modLcm[n1,n2])
而由于我们这里的 p i q i p_i^{q_i} piqi 之间一定是互素的,因此当所有的 p i q i p_i^{q_i} piqi 都满足条件时,他们的最小公倍数也就是他们全部乘起来,即 n n n。
由于 gcd ( a , n ) ≠ 1 \gcd(a,n)\ne1 gcd(a,n)=1 ,说明 a a a 肯定是至少是某一个 p i q i p_i^{q_i} piqi 的倍数。这个时候我们再分类讨论一下:
(Ⅰ) 当 gcd ( a , p i q i ) = 1 \gcd(a,p_i^{q_i})=1 gcd(a,piqi)=1 时
由引理 1我们知道 a b ≡ a b m o d φ ( n ) ( m o d n ) a^b\equiv a^{b\bmod\varphi(n)}\pmod n ab≡abmodφ(n)(modn),而这个 n n n 是 p i q i p_i^{q_i} piqi 的倍数,不难发现,如果我把这里的模数 n n n 缩小一定的倍数,即缩小到 p i q i p_i^{q_i} piqi,这个引理 1的式子依旧是成立的,于是有
a b ≡ a b m o d φ ( n ) ( m o d p i q i ) a^b\equiv a^{b\bmod\varphi(n)}\pmod {p_i^{q_i}} ab≡abmodφ(n)(modpiqi)
同理有
a φ ( n ) ≡ 1 ( m o d p i q i ) a^{\varphi(n)}\equiv1\pmod {p_i^{q_i}} aφ(n)≡1(modpiqi)
两边相乘即有
a b ≡ a b m o d φ ( n ) + φ ( n ) ( m o d p i q i ) a^b\equiv a^{b\bmod \varphi (n)+\varphi(n)}\pmod{ p_i^{q_i}} ab≡abmodφ(n)+φ(n)(modpiqi)
情况 (Ⅰ) 证毕。
(Ⅱ) 当 gcd ( a , p i q i ) ≠ 1 \gcd(a,p_i^{q_i})\ne1 gcd(a,piqi)=1 时
这种情况下, a a a 必然是 p i p_i pi 的倍数,假设 a = k p a=kp a=kp
这时就要用到我们的引理 2 了,我们都知道前提条件 b ≥ φ ( n ) b\geq\varphi(n) b≥φ(n) 以及引理 2 证明过的 φ ( p i q i ) ≥ q i \varphi(p_i^{q_i})\geq q_i φ(piqi)≥qi,因此有:
b ≥ φ ( n ) ≥ φ ( p i q i ) ≥ q i b\geq\varphi(n)\geq\varphi(p_i^{q_i})\geq q_i b≥φ(n)≥φ(piqi)≥qi
我们得到了 b ≥ q i b\geq q_i b≥qi,这可不得了了,那么我们就注意到此时 a b = ( k p ) b = k b p b a^b=(kp)^b=k^bp^b ab=(kp)b=kbpb 一定是 p i q i p_i^{q_i} piqi 的倍数
而 a b m o d φ ( n ) + φ ( n ) a^{b\bmod \varphi (n)+\varphi(n)} abmodφ(n)+φ(n) 也一定是 p i q i p_i^{q_i} piqi 的倍数!
因此既然这样,我们也就可以写出
a b ≡ a b m o d φ ( n ) + φ ( n ) ≡ 0 ( m o d p i q i ) a^b\equiv a^{b\bmod \varphi (n)+\varphi(n)}\equiv 0\pmod{ p_i^{q_i}} ab≡abmodφ(n)+φ(n)≡0(modpiqi)
证毕!
3. 应用:欧拉降幂
当我们计算 a b m o d p a^b \bmod p abmodp 时,我们通常采用快速幂来运算,但是当 b b b 非常非常非常大的时候,快速幂也显得有点乏力,此时我们可以用扩展欧拉定理去把 b b b 缩小,之后再采用快速幂运算就会快很多。
举个简单的例子:计算
99824435 3 98765472103312450233333333333 m o d 12345 998244353^{98765472103312450233333333333} \mod 12345 99824435398765472103312450233333333333mod12345
的时候,我们不能直接用快速幂,这个时候显然 98765472103312450233333333333 > φ ( 12345 ) 98765472103312450233333333333 > \varphi(12345) 98765472103312450233333333333>φ(12345),所以根据扩展欧拉定理,等价于计算
99824435 3 98765472103312450233333333333 m o d φ ( 12345 ) + φ ( 12345 ) m o d 12345 998244353^{98765472103312450233333333333 \bmod \varphi(12345) + \varphi(12345)} \mod 12345 99824435398765472103312450233333333333modφ(12345)+φ(12345)mod12345
最终的指数顶多也就 5 5 5 位数,之后再用快速幂就会快很多。
4. 【模板】扩展欧拉定理 ⭐⭐⭐⭐
【题目链接】
P5091 【模板】扩展欧拉定理 - 洛谷
【题目描述】
给你三个正整数, a , m , b a,m,b a,m,b,你需要求: a b m o d m a^b \bmod m abmodm
【输入格式】
一行三个整数, a , m , b a,m,b a,m,b
【输出格式】
一个整数表示答案
【示例一】
输入
2 7 4输出
2
【示例二】
输入
998244353 12345 98765472103312450233333333333输出
5333
【说明/提示】
注意输入格式, a , m , b a,m,b a,m,b 依次代表的是底数、模数和次数
【样例 1 1 1 解释】
2 4 m o d 7 = 2 2^4 \bmod 7 = 2 24mod7=2【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ a ≤ 1 0 9 1\le a \le 10^9 1≤a≤109, 1 ≤ b ≤ 1 0 20000000 , 1 ≤ m ≤ 1 0 8 1\le b \le 10^{20000000},1\le m \le 10^8 1≤b≤1020000000,1≤m≤108。
#include<iostream>using namespace std;typedef long long LL;LL a, m;
string s; // 由于 b 很大, 只能用 string 来存储// 公式法求单个数的欧拉函数
LL get_phi(LL x)
{LL ret = x;for(int i = 2; i <= x / i; i++){if(x % i == 0){ret = ret / i * (i - 1);while(x % i == 0) x /= i;}}if(x > 1) ret = ret / x * (x - 1);return ret;
}// 秦九韶 + 扩展欧拉
LL get_b(string& s, LL phi)
{// flag 标记 b 是否大于等于 phi(m)bool flag = false;LL ret = 0;for(auto& ch : s){ret = ret * 10 + ch - '0';// 如果 b >= phi(m), 此时满足降幂的使用条件if(ret >= phi){flag = true;ret %= phi; // 扩展欧拉}}if(flag) ret += phi; // 扩展欧拉return ret;
}// 快速幂
LL qpow(LL a, LL n, LL p)
{int ret = 1;while(n){if(n & 1) ret = ret * a % p;n >>= 1;a = a * a % p;}return ret;
}int main()
{cin >> a >> m >> s;LL phi_m = get_phi(m);LL b = get_b(s, phi_m);cout << qpow(a, b, m) << endl;return 0;
}
三、练习:上帝与集合的正确用法 ⭐⭐⭐⭐
【题目链接】
P4139 上帝与集合的正确用法 - 洛谷
【题目描述】
根据一些书上的记载,上帝的一次失败的创世经历是这样的:
第一天,上帝创造了一个世界的基本元素,称做元。
第二天,上帝创造了一个新的元素,称作 α \alpha α 。 α \alpha α 被定义为元构成的集合。容易发现,一共有两种不同的 α \alpha α 。
第三天,上帝又创造了一个新的元素,称作 β \beta β 。 β \beta β 被定义为 α \alpha α 构成的集合。容易发现,一共有四种不同的 β \beta β。
第四天,上帝创造了新的元素 γ \gamma γ, γ \gamma γ 被定义为 β \beta β 的集合。显然,一共会有 16 16 16 种不同的 γ \gamma γ。
如果按照这样下去,上帝创造的第四种元素将会有 65536 65536 65536 种,第五种元素将会有 2 65536 2^{65536} 265536种。这将会是一个天文数字。
然而,上帝并没有预料到元素种类数的增长是如此的迅速。他想要让世界的元素丰富起来,因此,日复一日,年复一年,他重复地创造着新的元素……
然而不久,当上帝创造出最后一种元素 θ \theta θ 时,他发现这世界的元素实在是太多了,以致于世界的容量不足,无法承受。因此在这一天,上帝毁灭了世界。
至今,上帝仍记得那次失败的创世经历,现在他想问问你,他最后一次创造的元素 θ \theta θ 一共有多少种?
上帝觉得这个数字可能过于巨大而无法表示出来,因此你只需要回答这个数对 p p p 取模后的值即可。
你可以认为上帝从 α \alpha α 到 θ \theta θ 一共创造了 1 0 9 10^9 109 次元素,或 1 0 18 10^{18} 1018 次,或者干脆 ∞ \infty ∞ 次。
【一句话题意】
定义 a 0 = 1 , a n = 2 a n − 1 a_0=1,a_n=2^{a_{n-1}} a0=1,an=2an−1,可以证明 b n = a n m o d p b_n=a_n\bmod p bn=anmodp 在某一项后都是同一个值,求这个值。
【输入格式】
第一行一个整数 T T T,表示数据个数。
接下来 T T T 行,每行一个正整数 p p p,代表你需要取模的值。
【输出格式】
T T T 行,每行一个正整数,为答案对 p p p 取模后的值。
【示例一】
输入
3 2 3 6输出
0 1 4
【说明/提示】
对于 100 % 100\% 100% 的数据, T ≤ 1 0 3 T\le 10^3 T≤103, p ≤ 1 0 7 p\le10^7 p≤107。
1. 解题思路
根据题意,实际上我们要求的就是
2 2 2 ⋯ m o d p 2^{2^{2\cdots}} \bmod p 222⋯modp
这样无限个 2 2 2 次幂模 p p p 最终等于多少。由于有无数个 2 2 2,显然指数 2 2 ⋯ > = φ ( p ) 2^{2\cdots} >= \varphi(p) 22⋯>=φ(p),我们可以采用欧拉降幂,因此等于计算
2 ( 2 2 ⋯ m o d φ ( p ) + φ ( p ) ) m o d p 2^{(2^{2\cdots} \bmod \varphi(p) + \varphi(p))} \bmod p 2(22⋯modφ(p)+φ(p))modp
显然这里需要用到递归,每一次的递归都需要求模数的欧拉函数,因此需要提前打表,递归终止条件为 p = 1 p = 1 p=1,此时式子的结果为 0 0 0。
2. 代码实现
#include<iostream>using namespace std;typedef long long LL;const int N = 1e7 + 10;
int p[N], phi[N];
bool vis[N];
int cnt;// 线性筛打表欧拉函数
void get_phi(int n)
{phi[1] = 1;for(LL i = 2; i <= n; i++){if(!vis[i]){p[cnt++] = i;phi[i] = i - 1;}for(LL j = 0; i * p[j] <= n; j++){LL x = i * p[j];vis[x] = true;if(i % p[j] == 0){phi[x] = phi[i] * p[j];break;}else{phi[x] = phi[i] * (p[j] - 1);}}}
}// 快速幂
LL qpow(LL a, LL n, LL p)
{LL ret = 1;while(n){if(n & 1) ret = ret * a % p;n >>= 1;a = a * a % p;}return ret;
}// 递归求解结果
int dfs(int p)
{if(p == 1) return 0;else return qpow(2, dfs(phi[p]) + phi[p], p);
}int main()
{get_phi(1e7);int t, p;cin >> t;while(t--){cin >> p;int ans = dfs(p);cout << ans << endl;}return 0;
}
