题目链接:
https://nanti.jisuanke.com/t/41299
题目:
In Complexity theory, some functions are nearly O(1)O(1), but it is greater then O(1)O(1). For example, the complexity of a typical disjoint set is O(nα(n))O(nα(n)). Here α(n)α(n) is Inverse Ackermann Function, which growth speed is very slow. So in practical application, we often assume α(n) \le 4α(n)≤4.
However O(α(n))O(α(n)) is greater than O(1)O(1), that means if nn is large enough, α(n)α(n) can greater than any constant value.
Now your task is let another slowly function log*log∗ xx reach a constant value bb. Here log*log∗ is iterated logarithm function, it means “the number of times the logarithm function iteratively applied on xx before the result is less than logarithm base aa”.
Formally, consider a iterated logarithm function log_{a}^*loga∗
Find the minimum positive integer argument xx, let log_{a}^* (x) \ge bloga∗(x)≥b. The answer may be very large, so just print the result xx after mod mm.
Input
The first line of the input is a single integer T(T\le 300)T(T≤300) indicating the number of test cases.
Each of the following lines contains 33 integers aa , bb and mm.
1 \le a \le 10000001≤a≤1000000
0 \le b \le 10000000≤b≤1000000
1 \le m \le 10000001≤m≤1000000
Note that if a==1, we consider the minimum number x is 1.
Output
For each test case, output xx mod mm in a single line.
Hint
In the 4-th4−th query, a=3a=3 and b=2b=2. Then log_{3}^* (27) = 1+ log_{3}^* (3) = 2 + log_{3}^* (1)=3+(-1)=2 \ge blog3∗(27)=1+log3∗(3)=2+log3∗(1)=3+(−1)=2≥b, so the output is 2727 mod 16 = 1116=11.
样例输入复制
5
2 0 3
3 1 2
3 1 100
3 2 16
5 3 233
样例输出复制
1
1
3
11
223
题目大意:
给你三个数a, b, m (范围见原题),问你log_{a}^*loga∗(x)>=b的最小x,很明显最小的x就是(幂塔函数),一共b个a。
那么这个东西应该怎么求呢?我们知道,欧拉定理可以用来进行降幂(如下,摘自百度百科)。
由此可得
那么对于这个题,我们直接套用公式即可,具体过程如下
定义为有b个a的幂塔函数在取模意义下的值,则
递归求解该公式即可,在进行快速幂的同时判断一下指数是否大于
但如果直接按照公式递归,显然递归层数太多,时间复杂度太高,注意到每次取的模都会变成,那么,也就是说,经过最多次迭代之后,模数就会变成1,那么显然算式的值就是0(正整数取模1都是0),这个时候我们就不会继续向下递归了。这样就可以AC本题啦0.0
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
ll qPow(ll a, ll b, ll MOD) {
ll ans = 1;
bool flag = false;
while (b) {
if (b & 1) {
if (ans * a >= MOD)
flag = true;
ans = (ans * a) % MOD;
}
if (b == 1)break;
if (a * a >= MOD)
flag = true;
a = (a * a) % MOD;
b >>= 1;
}
if (flag)
ans += MOD;
return ans;
}
ll phi(ll tx) {
ll ans = tx, len = sqrt(tx);
for (ll i = 2; i <= len; i++) {
if (tx % i == 0) {
ans = ans / i * (i - 1);
while (tx % i == 0) tx /= i;
}
}
if (tx > 1) ans = ans / tx * (tx - 1);
return ans;
}
ll f(ll a, ll b, ll p) {
if (p == 1) {
if (b != 0) return p;
return 0;
}
if (b == 0) return 1 % p;
if (b == 1) {
if (a >= p)
return (a % p) + p;
return (a % p);
}
ll tPhi = phi(p), tf = f(a, b - 1, tPhi);
return qPow(a, tf, p);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
ll a, b, p;
scanf("%lld %lld %lld", &a, &b, &p);
if (b == 0) {
printf("%lld\n", 1 % p);//注意!!!
continue;
}
ll tt = f(a, b - 1, phi(p));
printf("%lld\n", qPow(a, tt, p) % p);
}
return 0;
}