求a^b%c,(1 <= a,b <= 2^62, 1 <= c <= 10^9)
最主要的高速幂
_LL mod_exp(_LL a, _LL b, int c) { _LL ans = 1; _LL t = a%c; while(b) { if(b&1) ans = ans*t%c; t = t*t%c; b >>= 1; } return ans; }
由于c在long long范围内,中间两个long long 相乘的时候会超long long。所以对乘法再写一个高速乘法的函数,将乘法变为加法,每加一次就进行取模,就不会超long long了。
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) #define C 240 #define S 20 using namespace std; const int maxn = 110; // a*b%c LL mul_mod(LL a, LL b, LL c) { LL ans = 0; a %= n; b %= n; while(b) { if(b&1) { ans = ans+a; if(ans >= c) ans -= c; } a <<= 1; if(a >= c) a -= c; b >>= 1; } return ans; } //a^b%c LL pow_mod(LL a, LL b, LL c) { LL ans = 1; a = a%c; while(b) { if(b&1) ans = mul_mod(ans,a,c); a = mul_mod(a,a,c); b >>= 1; } return ans; } int main() { LL a,b,c; while(~scanf("%lld %lld %lld",&a,&b,&c)) { LL ans = pow_mod(a,b,c); printf("%lld ",ans); } return 0; }
求a^b%c (1 <= a,c <= 10^9, 1 <= b <= 10^1000000)
b相当大,高速幂超时。
有一个定理: a^b%c = a^(b%phi[c]+phi[c])%c,当中要满足b >= phi[c]。这样将b变为long long范围内的数,再进行高速幂。至于这个定理为什么成立,如今明确一点。这篇讲的挺具体:http://www.narutoacm.com/archives/a-pow-b-mod-m/
http://acm.fzu.edu.cn/problem.php?pid=1759
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) #define C 240 #define S 20 using namespace std; const int maxn = 110; LL a,c,cc; char b[1000010]; LL Eular(LL num) { LL res = num; for(int i = 2; i*i <= num; i++) { if(num%i == 0) { res -= res/i; while(num%i == 0) num /= i; } } if(num > 1) res -= res/num; return res; } bool Comper(char s[], LL num) { char bit[30]; int len2 = 0,len1; while(num) { bit[len2++] = num%10; num = num/10; } bit[len2] = '