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

该博客介绍了ICPC亚洲南京2019预选赛网络赛B题,涉及数论中的迭代对数函数log*log*。题目要求找到使log_a^*(x) >= b成立的最小正整数x,并模m后的结果。文章解释了如何利用欧拉定理和快速幂算法解决这个问题,并提供了代码实现。
摘要由CSDN通过智能技术生成

题目链接:

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。

那么这个东西应该怎么求呢?我们知道,欧拉定理可以用来进行降幂(如下,摘自百度百科)。

由此可得

那么对于这个题,我们直接套用公式即可,具体过程如下

定义f(a,b,c)为有b个a的幂塔函数在取模意义下的值,则

$$f(a,b,c) = \begin{cases} a\%p & b=1 \\ a^{f(a,b-1,\phi(c))+\phi(c)} & f(a,b-1,\phi(c)) \geq \phi(c)\\ a^{f(a,b-1,\phi(c)) & f(a,b-1,\phi(c)) < \phi(c)\\ \end{cases}$$

递归求解该公式即可,在进行快速幂的同时判断一下指数是否大于\phi(c)

但如果直接按照公式递归,显然递归层数太多,时间复杂度太高,注意到每次取的模都会变成\phi(c),那么,也就是说,经过最多log(b)次迭代之后,模数就会变成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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值