CF906D Power Tower(幂塔)

目录

Description

给定一个数列w1,w2,...,wnw_1,w_2,...,w_n和模数p,每次询问一个区间[l,r],求wlwl+1wl+2...wrmodpw_l^{w_{l+1}^{w_{l+2}^{{...}^{w_r}}}} mod p的值

State

\(1<=n<=10^{5}\)

\(q = 10^7+7\)

\(1<=w_k<=10^9\)

\(1<=l<=r<=n\)

Input

6 1000000000
1 2 2 3 3 3
8
1 1
1 6
2 2
2 3
2 4
4 4
4 5
4 6

Output

1
1
2
4
256
3
27
597484987

Solution

先给出扩展欧拉定理的结论:

\[a^c= \begin{cases} a^c \qquad \qquad \quad ϕ(b)>c \\ a^{c \% ϕ(b)+ϕ(b)} \quad ϕ(b)<=c \\ \end{cases} mod \ b \]

比如要计算:\(a^{b^c}\%m\),套娃开始了,首先需要知道 \(ϕ(m)\) 的值,这样才可以简化计算,假设一直按照 \(ϕ(b)<=c\) 的公式来计算

\[a^{b^c} \ = \ a^{b^c\%ϕ(m)+ϕ(m)} (mod \ m) \\ b^c\%ϕ(m)+ϕ(m)\ = b^c(mod \ ϕ(m)) \\ =b^{c\%ϕ(m)+ϕ(m)} \ (mod \ ϕ(m)) \]

为了保证复杂度,需要处理出 \(ϕ(ϕ(ϕ...(m)))\) 才可以,而且由于范围过大,需要用 \(map\) 来存储;

这里有一个小结论:

\(\color{red}{ϕ(ϕ(ϕ...(m))) 一定会收敛于 1, 而且处理出所有 ϕ(m) 的复杂度为 O(\sqrt{m}logm) }\)

简单证明一下,在 \(n>2\) 时,\(ϕ(n)\) 一定是一个偶数,因为 \((i)\)\((n-i)\) 一定同时 \((n)\) 互质,也就是说 \(gcd(i, n) = gcd(n-i, n)\);

\(ϕ(n)\) 一定与 \(1\) 是互质的,所以最终一定是 \(1\)

\(hack:\) 在使用快速幂解决的时候,只有最后一步是求最终答案,而其他的都是求指数部分,当然需要满足扩展欧拉定理的限制

const int N = 1e6 + 5;

    ll n, m, _;
    int i, j, k;
    ll a[N];

ll mo(ll x, ll mod)
{
    if(mod > x) return x;
    return x % mod + mod;
}

ll eular(ll x)
{
    ll ans = x;
    for (ll i = 2; i * i <= x; i++){
        if (x % i == 0){
            ans = ans / i * (i - 1);
            while (x % i == 0)
                x /= i;
        }
    }
    if (x > 1)
        ans = ans / x * (x - 1);
    return ans;
}

ll ksm(ll a, ll x, ll mod)
{
    ll ans = 1;
    while (x){
        if (x & 1)
            ans = mo(ans * a, mod);
        a = mo(a * a, mod);
        x >>= 1;
    }
    return ans;
}

map<ll, ll> phi;
ll dfs(int l, int r, ll mod)
{
    if(l == r) return mo(a[l], mod);
    if(mod == 1) return 1;
    ll exp = dfs(l + 1, r, phi[mod]);
    return ksm(a[l], exp, mod);
}

signed main()
{
    //IOS;
    int n, p;
    while(~ sdd(n, p)){
        rep(i, 1, n){
            sll(a[i]);
        }
        phi.clear();
        ll mod = p;
        while(mod > 1) phi[mod] = eular(mod), mod = phi[mod];
        phi[1] = 1;
        for(sd(m); m --> 0;){
            int l, r;
            sdd(l, r);
            pll(dfs(l, r, p) % p);
        }
    }
    return 0;
}
posted @ 2021-08-13 14:44  Bcoi  阅读(189)  评论(0)    收藏  举报