洛谷 P5091 欧拉降幂

https://www.luogu.org/problemnew/show/P5091

题目背景

模板题,无背景

题目描述

给你三个正整数,a,m,b你需要求:
a^b mod m

输入输出格式

输入格式:

一行三个整数,a,m,b

输出格式:

一个整数表示答案

输入输出样例

输入样例#1: 复制

2 7 4

输出样例#1: 复制

2

输入样例#2: 复制

998244353 12345 98765472103312450233333333333

输出样例#2: 复制

5333

说明

注意输入格式,a,m,b依次代表的是底数、模数和次数

数据范围:
对于全部数据:
1≤a≤10^9
1≤b≤10^20000000
1≤m≤10^6

 这是广义降幂公式不要求A与C互质!当B<φ(C)时,就没有降幂的必要了。

公式中的φ(C)是欧拉函数,不知道的可以百度了解一哈:

https://baike.baidu.com/item/欧拉函数/1944850?fr=aladdin

#include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
#include<cstring>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

ll euler(ll n)	//得到φ(n)
{
    ll ret=n,i;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            n/=i;
            ret=ret-ret/i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)//素数情况
        ret=ret-ret/n;
    return ret;
}


ll quickpow(ll a,ll b,ll d)//计算a^b%d
{
    ll t1=1,t2=a;
    while(b>0)
    {
        if(b&1)
            t1=t1*t2%d;
        t2=t2*t2%d;
        b>>=1;
    }
    return t1;
}

int main()
{
    ll a,c;
    scanf("%lld%lld",&a,&c);
    ll oula=euler(c);
    ll sum=0;
    int flag=0;
    char ch;
    ch=getchar();
    if(ch<'0'||ch>'9')
        ch=getchar();
    while(ch>='0'&&ch<='9')
    {
        sum=sum*10+ch-48;
        if(sum>=oula)
        {
            flag=1;
            sum%=oula;
        }
        ch=getchar();
    }
    if(flag)
        sum+=oula;
    printf("%lld\n",quickpow(a,sum,c));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/87794341