欧拉降幂模板(洛谷P5091)

题意:
给出 a , b , m ( 1 ≤ a ≤ 1 0 9 , 1 ≤ b ≤ 1 0 20000000 , 1 ≤ m ≤ 1 0 8 ) a,b,m(1\leq a \leq 10^9,1 \leq b \leq 10^{20000000 },1 \leq m \leq 10^8) a,b,m(1a109,1b1020000000,1m108)求: a b a^b ab% m m m
题解:
什么叫欧拉降幂??这种题就用欧拉降幂,幂数太大!!!必须要把b用某种方法降下来,这种方法就是欧拉降幂!!

这就是欧拉公式了在这里插入图片描述
对于这道题而言,我们只需要找到 m o d mod mod的欧拉函数和 b b b的相对大小就可以了。此前我已经细讲了欧拉函数打表欧拉,不了解的可以翻一翻我之前的博客,另外,这题的模数是10的8次方,开空间是开不下的,需要取巧求一下欧拉函数
code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e4+5;
int prime[maxn/10],phi[maxn],tot,mod,pmod=1;
void Euler(){
    phi[1]=1;
    for(int i=2;i<maxn;i++){
        if(!phi[i]){
            phi[i]=i-1;
            prime[tot++]=i;
        }
        for(int j=0;j<tot&&prime[j]*i<maxn;j++){
            if(i%prime[j]==0){
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
    int smod=mod;
    for(int i=0;prime[i]*prime[i]<=smod;i++){
        if(smod%prime[i]==0){
            smod/=prime[i];
            pmod*=(prime[i]-1);
            while(smod%prime[i]==0)pmod*=prime[i],smod/=prime[i];
        }
    }
    if(smod!=1)pmod*=(smod-1);
}
ll fast(ll x,ll y){
    ll ans=1;
    while(y){
        if(y&1)ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}
inline ll read(bool &f){
    ll x=0;char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))
        x=(x<<1)+(x<<3)+(ch^48),f|=x>=pmod,x%=pmod,ch=getchar();
    return x;
}
int main(){
    ll a;
    bool flag=false;
    cin>>a>>mod;
    Euler();
    ll b=read(flag);
    if(__gcd(a,mod*1ll)!=1&&flag)b+=pmod;
    cout<<fast(a,b);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Macarons_i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值