--
快速幂加强版
网上有关的资料很少,好难找。。还是搜索水平不够
数论的题每次做都有一种好厉害的感觉
首先你需要知道φ(m),这是欧拉函数,表示小于m的整数中与m互质的个数
使用了广义欧拉定理
a^b≡a^(b%φ(m)+φ(m))(mod m) (b > φ(m) )
这样就大大降次了。
对于b < φ(m)的情况,直接使用快速幂计算,因为此时b很小
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> using namespace std; long long fast_mod(long long a,long long b,long long y){ long long ans = 1; a = a % y; while (b > 0){ if (b & 1) ans = (ans*a) % y; b = b / 2; a = (a*a) % y; } return ans; } long long eular(long long n){ long long res = 1; long long p = 2; while (p*p <= n){ if (n % p == 0){ res*= (p-1); n /= p; while (n % p == 0){ res *= p; n/=p; } } p++; } if (n!=1){ res*=(n-1); } return res; } long long gcd(long long a,long long b){ if (a < b) return gcd(b,a); if (b == 0) return a; else return gcd(b,a%b); } long long power(long b,long c){ if (c == 1) return b; long long res = power(b,c/2); if (c % 2 == 0) return res*res; else return res*res*b; } long long solve(long long a,long long b,long long c,long long y){ long long fai = eular(y); if (log(fai)/log(b) < c) return fast_mod(a,fast_mod(b,c,fai)+fai,y); else return fast_mod(a,power(b,c),y); } int main(){ long long a,b,c,y; while (scanf("%lld %lld %lld %lld",&a,&b,&c,&y) != EOF){ printf("%lld ",solve(a,b,c,y)); //printf("%lld ",power(b,c)); } return 0; }
参考资料:
http://blog.csdn.net/guhaiteng/article/details/52588223