FZU1759 Super A^B mod C(欧拉降幂+快速幂)

Super A^B mod C

题目链接: https://cn.vjudge.net/problem/FZU-1759

题目:

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)%c,但是b的范围是非常非常大的。

思路:

所以要先欧拉降幂。然后使用快速幂即可。

首先先说一下欧拉函数,欧拉函数是指,对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记住φ(n) 。

欧拉函数通式:φ(x) = x(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pn),其中p1,p2,…pn为x的所有质因数,x是不为0的整数,φ(1) = 1(唯一和1互质的就是1)。
欧拉函数的性质:
①对于质数x,它的φ(x) = x-1; 注意φ(1) = 1.

②它是积性函数。积性函数:若当m与n互质时,f(m*n)=f(m)f(n),那么f是积性函数。若对任意正整数,都有f(mn)=f(m)*f(n)成立,则f是完全积性函数。

③当n为奇数时,φ(2n)=φ(n)

④若n是质数p的k次幂,φ(n)=pk-p(k-1) = (p-1)*p^(k-1)。因为除了p的倍数外,其他数都跟n互质。

欧拉函数代码:

ll ol(ll x)
{
	ll i,res=x;
	for(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;
}


降幂公式img

算出Bmodφ©+φ©,然后跑快速幂即可。

代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
ll ol(ll x)
{
    ll i, res = x;
    for(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;
}
ll quickMod(ll a, ll b, ll c)
{
    ll ans = 1;
    while(b){
        if(b & 1) {
            ans = (ans * a) % c;
        }
        a = (a * a)%c;
        b >>= 1;
    }
    return ans % c;
}
int main()
{
    ll a, c;
    string b;
    while(cin >> a >> b >> c) {
        ll phi = ol(c);
        ll sum = 0;
        for(int i = 0; i < b.length(); i++)
            sum = (sum * 10 + b[i] - '0') % phi;
        sum = sum + phi;
        cout << quickMod(a,sum,c) << endl;
    }
    return 0;
}

你可能感兴趣的:(数论)