[欧拉降幂][2019南京网络赛B]super_log

Posted lllxq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[欧拉降幂][2019南京网络赛B]super_log相关的知识,希望对你有一定的参考价值。

题意:输入a,b,p,求技术图片(底数a的右上角有b-1个a)

思路: 

广义欧拉定理:

技术图片

AC代码:

技术图片
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

ll a,b,m;
ll vis[1000005];
ll prime[1000005],num=0;
ll phi[1000005];

void getphi(ll n=1000000)
    phi[1]=1;
    for(ll i=2;i<=n;i++)
        if(!vis[i]) prime[++num]=i,phi[i]=i-1;
        for(ll j=1;j<=num;j++)
            ll k=i*prime[j];
            if(k>n)break;
            vis[k]=1;
            if(i%prime[j]==0)
                phi[k]=phi[i]*prime[j];
                break;
            
            phi[k]=phi[i]*(prime[j]-1);
        
    
    return;


ll qpow(ll a,ll b,ll mod)
  ll ret=1;
  while(b)
    if(b&1) ret=ret*a%mod;
    a=a*a%mod;
    b>>=1;
  
  return ret;


ll check(ll d,ll cmp)
  ll res=a;
  for(ll i=1;i<=d;i++)
    ll tmp=1;
    for(ll j=1;j<=res;j++)
        tmp=tmp*a;
        if(tmp>=cmp) return 1;
    
    res=tmp;
  
  return -1;


ll fun(ll d)
  ll res=a;
  for(ll i=1;i<=d;i++)
    ll tmp=1;
    for(ll j=1;j<=res;j++) tmp=tmp*a;
    res=tmp;
  
  return res;


ll cal(ll d,ll p)
  if(p==1) return 0;

  if(d==0) return a%p;

  ll tmp;
  if(__gcd(a,p)==1) tmp=cal(d-1,phi[p]);//gcd(a,p)==1
  else
      if(check(d-1,phi[p])<0) tmp=fun(d-1);//gcd(a,p)!=1&&b<phi(p)
      else tmp=cal(d-1,phi[p])+phi[p];//gcd(a,p)!=1&&b>=phi(p)
  
  ll ret=qpow(a,tmp,p);
  return ret;


int main()

    getphi();
    ll t;scanf("%lld",&t);
    while(t--)
        scanf("%lld%lld%lld",&a,&b,&m);
        if(a==1||b==0)
            printf("%lld\\n",1%m);
            continue;
        
        ll ans=cal(b-1,m);
        printf("%lld\\n",ans%m);
    
    return 0;
View Code

 

以上是关于[欧拉降幂][2019南京网络赛B]super_log的主要内容,如果未能解决你的问题,请参考以下文章

2019ICPC网赛南京站B题 super_log(欧拉降幂

2019ICPC南京网络赛B super_log——扩展欧拉定理

ACM-数论-广义欧拉降幂

2018焦作网络赛G

广义欧拉降幂

[数学][欧拉降幂定理]Exponial