题目描述:
输入三个正整数a,b,c 计算a^b mod c。
输入格式:
第一行输入三个正整数a,b,c。
输出格式:
输出a^b mod c 的值。
样例输入输出:
Mod.in mod.out
2 3 5 3
数据范围:
30%的数据满足:a,c*c 在longint 范围内,b<=10000;
50%的数据满足:a,b,c*c 都在longint 范围内;
100%的数据满足:a,b,c 在longint 范围内。
这里的幂的运算,如果要循环来mod的话,复杂度就是O(b)了,时间明显不过啊。
所以,就有一种十分鬼畜的算法:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <string> #include <cmath> using namespace std; typedef long long ll; ll a,b,c; ll read() { ll ans = 0; char ch = getchar(),last = ' '; while(ch < '0' || ch > '9') last = ch , ch = getchar(); while(ch >= '0' && ch <= '9') ans = ans * 10 +ch - '0' , ch = getchar(); if(last == '-') ans = -ans; return ans; } void put(ll x) { if(x < 0) { putchar('-'); x = -x; } if(x == 0) { putchar('0'); return; } ll q[100] , nn = 0; while(x) q[++ nn] = x % 10 , x /= 10; while(nn) putchar('0' + q[nn]), --nn; } ll jiafa(ll a,ll b,ll c) { if (a + b >= a) return (a + b) % c; return (a % c + b % c - c); } ll chengfa(ll a,ll b,ll c ) { if (a * b / a == b) return (a * b) % c; ll d = 0 ; for (ll i = a ; b ; i = jiafa(i,i,c) , b /= 2) { if ((b % 2) != 0) d = jiafa(d,i,c); } return d; } ll mi(ll a,ll b,ll c) { ll d = 1; for (ll i = a ; b ; i = chengfa(i,i,c),b /= 2) { if ((b % 2) != 0) d = chengfa(d,i,c); } return d; } int main() { freopen("mod.in","r",stdin); freopen("mod.out","w",stdout); a = read(); b = read(); c = read(); put(mi(a,b,c)); return 0; }
因为幂的运算是基于加与乘的基础上的,a^b就可以看成b个a相乘,所以加的mod来解决每次每个数的mod,乘的mod来解决每次乘的mod,最后mi的mod是用来将前两项整合用的。因此就可以算出a^b%c的数了。