bzoj 3884 19南京區域賽網絡賽 B. super_log(擴展歐拉定理)

BZOJ 3844

19南京B. super_log

 

 

擴展歐拉定理 

                      

BZOJ 3844 傳送門  (冪塔函數)

題意:                  給你p求值。

思路:擴展歐拉。

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e7+10;
ll tao(ll n)//求[1,n)中與n互質的數的個數
{
    ll ans=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 ans;
}
ll MOD(ll a,ll mod)
{
    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 p)
{
    if(p==1)
        return MOD(1,p);
    return power(2,solve(tao(p)),p);
}
int main()
{
    printf("%lld\n",tao());
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll p;
        scanf("%lld",&p);
        printf("%lld\n",solve(p)%p);
    }
    return 0;
}

19南京區域賽網絡賽  B. super_log

題意:求a^(a^(a^(a^(...))),一共有b個a,求對於mod取餘後的結果。

思路:擴展歐拉          

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e7+10;
bool vis[N];        //質數爲0 素數爲1
ll prime[N];            //1-N 所有質數
ll phi[N];              //歐拉篩
void init(ll N)        //[1-N)範圍內 素數歐拉篩
{
    mems(vis,false);
    vis[0]=vis[1]=true;
    phi[1] = 1;
    ll cnt = 0;
    for(ll i = 2; i < N; i ++)
    {
        if(!vis[i]){
            prime[cnt++] = i;
            phi[i] = i - 1;
        }
        for(ll j = 0; j < cnt && i * prime[j] < N; j ++)
        {
            vis[i * prime[j]] = true;
            if(i % prime[j] == 0){
                phi[i*prime[j]] = phi[i]*prime[j];
                break;
            }
            else{
                phi[i*prime[j]] = phi[i]*phi[prime[j]];   // phi[i]*(prime[j]-1);
            }
        }
    }
}
ll tao(ll n)//求[1,n)與n互質的數的數目
{
    ll ans=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 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==0)
        return MOD(1,mod);
    if(mod==1)
        return MOD(a,mod);
    return power(a,solve(a,b-1,phi[mod]),mod);
}
int main()
{
    init(1e6+5);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll a,b,m;
        scanf("%lld%lld%lld",&a,&b,&m);
        printf("%lld\n",solve(a,b,m)%m);
    }
    return 0;
}

 

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