数论 FZU1759 降幂公式(欧拉函数+快速幂)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DADDY_HONG/article/details/81813134

Problem 1759 Super A^B mod C

Accept: 1682    Submit: 5719
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000).

 Input

There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a single space.

 Output

For each testcase, output an integer, denotes the result of A^B mod C.

 Sample Input

3 2 4

2 10 1000

 Sample Output

1

24

a^b mod c = ?

b<=10^1000000,超级大数了,a,c均为long long范围内。

因为数据很大所以本题用降幂公式,嘛我的菜鸡水平也只能直接套公式了嘤

降幂公式

φ(m)(phi哈哈哈哈是这个音来着)是欧拉函数。

那么

欧拉函数

对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记作φ(n) 。

φ(1)=1。(唯一和1互质的数就是1本身)。

对于质数p,φ(p) = p - 1。(除去它本身)

欧拉定理:对于互质的正整数a和n,有a^φ(n) ≡ 1 mod n。

欧拉函数是积性函数:若m,n互质,φ(mn)=φ(m)φ(n)(积性函数表达式)。

那么思考,n是质数p的k次幂,有φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。

欧拉函数的性质:

设p为n的质因数,

若(n % p == 0 && (n / p) % p == 0) 则有φ(n)=φ(n / p) * p;

若(n % p == 0 && (p / p) % p != 0) 则有:φ(n) = φ(n / p) * (p - 1)。

求欧拉函数:

法一:

long long euler(long long x)  //直接求欧拉函数 //还有一种线性筛法
{
    long long res=1;
    for(long long i=2;i*i<=x;++i){
        if(x%i==0){
            x/=i;
            res*=(i-1);
            while(x%i==0){
                x/=i;
                res*=i;
            }
        }
    }
    if(x>1) res*=(x-1);
    return res;
}

法二:

//求欧拉函数 相当于不断减去
long long phi(long long x)
{
    long long res=x;
    for(long long i=2;i*i<=x;++i){
        if(x%i==0){
            res=res-res/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res=res-res/x;
    return res;
}

本题只需套公式,先求出c的欧拉函数,大数b不断读入不断模,(高位的能模的最后的数也能模掉这样子),得出新的次方数b,再进行对a^newb mod c进行快速幂即可。

注:本题需用%I64d。

代码:

#include <cstdio>
#include <cstring>
#define LL long long

const int maxc=1e6+20;

long long a,c,phic,numb;
char b[maxc];

long long euler(long long x)  //直接求欧拉函数 //还有一种线性筛法
{
    long long res=1;
    for(long long i=2;i*i<=x;++i){
        if(x%i==0){
            x/=i;
            res*=(i-1);
            while(x%i==0){
                x/=i;
                res*=i;
            }
        }
    }
    if(x>1) res*=(x-1);
    return res;
}

long long qpow(long long a,long long n,long long mod)     //快速幂
{
    long long ans=1;
    while(n){
        if(n&1){
            ans*=a;
            ans%=mod;
        }
        a=(a*a)%mod;
        n>>=1;  //一定不要再忘记=了orz
    }
    return ans;
}

int main()
{
    while(~scanf("%I64d%s%I64d",&a,b,&c)){
        numb=0;
        phic=euler(c);
        int len=strlen(b);
        for(int i=0;i<len;++i)
            numb=(numb*10+(b[i]-'0'))%phic;
        numb+=phic;
        printf("%I64d\n",qpow(a,numb,c));
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/DADDY_HONG/article/details/81813134
今日推荐