Super A^B mod C (费马小定理的推广——欧拉定理)

题目链接:点击打开链接

题意:求a^b mod c的值,a,c为long long,b可能非常非常大,需要用字符串。

思路;

首先求下b的值,如果b小于c的话不能用欧拉定理,直接快速幂即可。

如果b非常非常大的话,就要用到欧拉定理。

费马小定理的推广——欧拉定理

模数 p 从素数推广到一般整数 n



欧拉降幂公式


我们需要先求欧拉函数,欧拉的递推式为:


代码为:

int phi(int x)//欧拉函数
{
	int i,j;
	int num = x;
	for(i = 2; i*i <= x; i++)
	{
		if(x % i == 0)
		{
			num = (num/i)*(i-1);
			while(x % i == 0)
			{
				x = x / i;
			}
		}
	}
	if(x != 1) num = (num/x)*(x-1);
	return num;
}

接下来就是求b对c的函数值phi求模,最后在加上一个phi。求快速幂即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
using namespace std;
#define maxn 1000050
char b[maxn];
long long a,c;
long PHI;
int phi(int x)//欧拉函数
{
	int i,j;
	int num = x;
	for(i = 2; i*i <= x; i++)
	{
		if(x % i == 0)
		{
			num = (num/i)*(i-1);
			while(x % i == 0)
			{
				x = x / i;
			}
		}
	}
	if(x != 1) num = (num/x)*(x-1);
	return num;
}
long long power(long long a,long long b,long long c)//快速幂
{
	long long base=a,sum=1;
	while(b!=0)
	{
		if(b&1)
		sum=(sum*base)%c;
		base=(base*base)%c;
		b>>=1;
	}
	return sum%c;
}
int main()
{
	while(~scanf("%lld%s%lld",&a,b,&c))
	{
		PHI=phi(c);//c的欧拉函数
		int len=strlen(b);
		long long num=0;
		for(int i=0;i<len;i++)//大数取模 同余模定理
		{
			num=(num*10+(int)(b[i]-'0'));
			if(num>c)break;
		}
		if(num<=c)
		{
			printf("%lld\n",power(a,num,c));
		}
		else
		{
			num=0;
			for(int i=0;i<len;i++)//大数取模 同余模定理
			{
				num=(num*10+(int)(b[i]-'0'))%PHI;

			}
			num+=PHI;
			printf("%lld\n",power(a,num,c));
		}

	}
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值