ASC7 Problem E. Strange Limit
题目大意
求$p^{p^{p^{.^{.^{.}}}}} \mod m!$
简要题解
由欧拉定理,有对任意$a,b,c$当$b$足够大时,有$a^b \equiv a^{b \mod \varphi(c) +\varphi(c)} \mod c$,设$x$为对$c=m!$取模的所求,$y$为对$c=\varphi(m!)$的所求,可以得到$x=a^{y+\varphi(c)}\mod c$,递归做即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace my_header { 4 #define pb push_back 5 #define mp make_pair 6 #define pir pair<int, int> 7 #define vec vector<int> 8 #define pc putchar 9 #define clr(t) memset(t, 0, sizeof t) 10 #define pse(t, v) memset(t, v, sizeof t) 11 #define bl puts("") 12 #define wn(x) wr(x), bl 13 #define ws(x) wr(x), pc(' ') 14 const int INF = 0x3f3f3f3f; 15 typedef long long LL; 16 typedef double DB; 17 inline char gchar() { 18 char ret = getchar(); 19 for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar()); 20 return ret; } 21 template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) { 22 for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar()); 23 if (c == '-') { flg = -1; c = getchar(); } 24 for(ret = 0; '0' <= c && c <= '9'; c = getchar()) 25 ret = ret * 10 + c - '0'; 26 ret = ret * flg; } 27 inline int fr() { int t; fr(t); return t; } 28 template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } 29 template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); } 30 template<class T> inline char wr(T a, int b = 10, bool p = 1) { 31 return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 32 (wr(a/b, b, 0), pc('0' + a % b))); 33 } 34 template<class T> inline void wt(T a) { wn(a); } 35 template<class T> inline void wt(T a, T b) { ws(a), wn(b); } 36 template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); } 37 template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); } 38 template<class T> inline T gcd(T a, T b) { 39 return b == 0 ? a : gcd(b, a % b); } 40 template<class T> inline T fpw(T b, T i, T _m, T r = 1) { 41 for(; i; i >>= 1, b = b * b % _m) 42 if(i & 1) r = r * b % _m; 43 return r; } 44 }; 45 using namespace my_header; 46 47 const int PRIME = 300000; 48 int vis[PRIME], pcnt, pri[PRIME]; 49 50 void sieve() { 51 for (int i = 2; i < PRIME; ++i) 52 if (pri[i] == 0) { 53 for (int j = i; j < PRIME; j += i) 54 pri[j] = 1; 55 pri[++pcnt] = i; 56 } 57 } 58 59 int gcd(int a, int b) { 60 return b == 0 ? a : gcd(b, a % b); 61 } 62 63 LL getPhi(LL t) { 64 LL ret = 1; 65 for (int i = 1; i <= pcnt; ++i) { 66 if (t % pri[i] == 0) { 67 ret *= pri[i] - 1; 68 t /= pri[i]; 69 while (t % pri[i] == 0) { 70 t /= pri[i]; 71 ret *= pri[i]; 72 } 73 } 74 } 75 return t == 1 ? ret : t - 1; 76 } 77 78 LL solve(LL a, LL b) { 79 if (b == 1) 80 return 0; 81 int phi = getPhi(b); 82 //wt(phi); 83 return fpw(a, solve(a, phi) + phi, b); 84 } 85 86 int main() { 87 #ifdef lol 88 freopen("E.in", "r", stdin); 89 freopen("E.out", "w", stdout); 90 #else 91 freopen("limit.in", "r", stdin); 92 freopen("limit.out", "w", stdout); 93 #endif 94 sieve(); 95 int p, m; 96 fr(p, m); 97 LL t = 1; 98 for (int i = 1; i <= m; ++i) 99 t = t * i; 100 wt(solve(p, t)); 101 102 return 0; 103 }