[bzoj3884]上帝与集合的正确用法

题意:求${2^{{2^{{2^{...}}}}}}\bmod p$

解题关键:

因为${a^n} \equiv {a^{n\bmod \varphi (p) + \varphi (p)}}\bmod p,n > \varphi (p)$

所以,

$\begin{array}{l}
f(p) = {2^{{2^{{2^{...}}}}}}\bmod p = {2^{{2^{{2^{...}}}}\bmod \varphi (p) + \varphi (p)}}\bmod p\\
= {2^{f(\varphi (p)) + \varphi (p)}}\bmod p
\end{array}$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<cmath>
 7 using namespace std;
 8 typedef long long ll;
 9 const int MAXN=10000000+10;
10 int prime[MAXN];//保存素数
11 bool vis[MAXN];//初始化
12 int phi[MAXN];//欧拉函数
13 void Lphisieve(int n){
14     int cnt=0;
15     for(int i=2;i<n;i++){
16         if(!vis[i]){
17             prime[cnt++]=i;
18             phi[i]=i-1;
19         }
20         for(int j=0;j<cnt&&i*prime[j]<n;j++){
21             int k=i*prime[j];
22             vis[k]=true;
23             if(i%prime[j]==0){
24                 phi[k]=phi[i]*prime[j];
25                 break;
26             }
27             else   phi[k]=phi[i]*(prime[j]-1);
28         }
29     }
30 }
31 
32 ll mod_pow(ll x,ll n,ll p){
33     ll res=1;
34     while(n){
35         if(n&1)   res=res*x%p;
36         x=x*x%p;
37         n>>=1;
38     }
39     return res;
40 }
41 
42 ll work(ll n){
43     if(n==1) return 0;
44     return mod_pow(2,work(phi[n])+phi[n],n);
45 }
46 
47 int main(){
48     int T;
49     Lphisieve(10000001);
50     scanf("%d", &T);
51     while(T--){
52         ll n;
53         scanf("%lld",&n);
54         printf("%lld\n",work(n));
55     }
56     return 0;
57 }

 

转载于:https://www.cnblogs.com/elpsycongroo/p/7858099.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值