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

来源:互联网 发布:情话知乎 编辑:程序博客网 时间:2024/04/30 11:02

题目链接:点击打开链接

题意:求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 1000050char 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;}



原创粉丝点击