FZU 1759-Super A^B mod C (欧拉函数+降幂公式)

Problem 1759 Super A^B mod C

Accept: 936    Submit: 3059
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 42 10 1000

Sample Output

124

Source



求a的b次方余c,然而b是一个超大整数,远远大于long long 的表示范围,但是你用大整数乘法也做不了,
因为要取模。。。。呢就直接切入正题好了,既然幂次很大,呢肯定是要降幂了,其实做这道题你就能想到
肯定有一种降幂公式,因为要用到欧拉函数,呢这里就讲一下欧拉函数的具体概念及其求法好了。。。


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

通式:φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)。

对于质数p,φ(p) = p - 1。注意φ(1)=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互质。


特殊性质:当n为奇数时,φ(2n)=φ(n)

欧拉函数还有这样的性质:

设a为N的质因数,若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 则有:E(N) = E(N / a) * (a - 1)。

求欧拉函数的具体代码:
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;
}
欧拉函数知道后,呢就直接上降幂公式了,该公式的证明就不在说了,挺难的。
直接上公式吧,毕竟还是很好记的。。。。

降幂公式:     ( 降幂公式中 phi() 为欧拉函数)


#include<map>  
#include<stack>  
#include<queue>  
#include<vector>  
#include<math.h>  
#include<stdio.h>  
#include<iostream>  
#include<string.h>  
#include<stdlib.h>  
#include<algorithm>  
using namespace std;  
typedef __int64  ll;  
#define inf 1000000000  
#define mod 1000000007 
#define  maxn  1000006
#define  lowbit(x) (x&-x)  
#define  eps 1e-10  
char s[maxn];
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 q(ll x,ll y,ll MOD)
{
	ll res=1;
	while(y)
	{
		if(y%2)
			res=res*x%MOD;
		x=x*x%MOD;
		y/=2;
	}
	return res;
}
int main(void)
{
	ll a,c,i,ans,tmp,b;
	while(scanf("%I64d%s%I64d",&a,s,&c)!=EOF)
	{
		ans=0;b=0;tmp=ol(c);
		ll len=strlen(s);
		for(i=0;i<len;i++)
			b=(b*10+s[i]-'0')%tmp;
		b+=tmp;
		ans=q(a,b,c);
		printf("%I64d\n",ans);
	}
	return 0;
}





  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值