CF 906D - Power Tower (冪塔函數 -擴展歐拉定理)

一個鏈接:https://www.cnblogs.com/violet-acmer/articles/11451240.html

 

D. Power Tower

題意:                                     求L至R取餘m的值。

思路:擴展歐拉定理

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <map>
#include <iterator>
#include <vector>
#include <set>
#include <bitset>
#include <stack>
#define ull unsigned long long
#define Mod(x) (x+mod)%mod
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll mod=1e9+7;;
const int N=1e5+10;
ll h[N];
map<ll,ll>mp;
ll tao(ll n)//求[1,n)與n互質的數的數目
{
    ll ans=n;
    ll tt=n;
    if(mp[n])
        return mp[n];
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            ans-=ans/i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        ans-=ans/n;
    return mp[tt]=ans;
}
ll MOD(ll a,ll mod)//這裏就實現了判斷x是否大於φ(p);
{//定理的二三
    if(a<mod)
        return a;
    return a%mod+mod;
}
ll power(ll a,ll b,ll c)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=MOD(ans*a,c);
        }
        b>>=1;
        a=MOD(a*a,c);
    }
    return ans;
}
ll solve(ll a,ll b,ll mod)
{
    if(b==a)
        return MOD(h[a],mod);
    if(mod==1)
        return MOD(h[a],mod);
    return power(h[a],solve(a+1,b,tao(mod)),mod);///這裏a+1,看上面思路
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&h[i]);
    }
    int q;
    scanf("%d",&q);
    for(int i=0;i<q;i++)
    {
        ll l,r;
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",solve(l,r,m)%m);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章