標籤:超級冪 數論
題目大意
以若干行的形式給定若干組a,b,c(你不知道有多少組),輸出若干行,每行代表相應的abmodc的值。其中1≤a,c≤1000000000,1≤b≤101000000
評測網址
http://acm.fzu.edu.cn/problem.php?pid=1759
- 題解
資料真的很大。。。。。
不過我們有公式:
abmodc=a(bmodφ(c))+φ(c)modc,b≥φ(c);
把它記為(*)式。
我們可以把b先用字串ch讀入,再從高位到低位處理:
for(int i = 0; i < strlen(ch); ++i){ b = b * 10 + ch[i] - 48; b %= phi(c);}
這很好理解,因為若一個數可以被φ(c)整除,這個數又是一個大數的前面若干位,那麼這個大數前面若干位一定也可以被φ(c)整除,那麼直接把這幾位丟掉即可。所以可以對ch串邊擴大邊模數,得到的b就自然在φ(c)的範圍內了。根據(*)式,這樣不影響正確答案,然後上快速冪即可A掉本題。
注意事項
提交時若使用scanf或printf輸出long long或__int64,不能用”%lld”,只能用”%I64d”。
Code
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define ll long longusing namespace std;char ch[1000010];inline ll singleEulerPhi(ll a){ ll ans = a; for(ll i = 2; i <= (ll)sqrt(a * 10); ++i) if(a % i == 0) { ans = ans / i * (i - 1); while(a % i == 0) a /= i; } if(a > 1) ans = ans / a * (a - 1); return ans;}inline ll quickPow(ll a, ll b, ll m){ ll ans = 1; for(ll t = a; b; b >>= 1, t = (t % m) * (t % m) % m) if(b & 1) ans = (ans % m) * (t % m) % m; return ans;}inline void write(ll a){ int top = 0; char ch[50]; if(a < 0) { putchar(‘-‘); a = -a; } do { ch[top++] = a%10 + 48; a /= 10; } while(a); while(top--) putchar(ch[top]); putchar(‘\n‘);}int main(){ ll a, b, c, phi, len; while(scanf("%I64d", &a) == 1) { scanf("%s", &ch); scanf("%I64d", &c); len = strlen(ch); phi = singleEulerPhi(c); b = 0LL; for(int i = 0; i < len; ++i) { b = b * 10 + ch[i] - 48; b %= phi; } write(quickPow(a, b, c)); } return 0;}
Fzu1759 Super A^B mod C 題解