这题其实就是快速求一个高次幂的模。
这是题目的答案
#include<iostream> #include<cmath> using namespace std; int a[45002]; int b[45002]; int mod(int a, int b, int c) { int z = 1; while(b) { if(b%2) z = (z*a)%c; b/=2; a = (a*a)%c; } return z; } int main() { int T; cin>>T; while(T--) { int M; int H; cin>>M>>H; for(int i=0; i<H; i++) { cin>>a[i]>>b[i]; } int t =0; int mode = 0; while(t<H) { int tem0 = a[t]%M; mode = (mod(tem0,b[t],M) + mode)%M; t++; } cout<<mode<<endl; } }
只分析求幂—模的那个函数,先举例吧(a a a a a a a a a a)这是b个a (b =10),通过z来记录二分时多出来的一个a,每次二分后用a来代替a*a,这样就得到了缩小规模的结果。最后肯定是b=1,所以这时只需用现在的a与z结合就是最后的结果了。
int mod(int a, int b, int c) { int z = 1; while(b) { if(b%2) z = (z*a)%c; b/=2; a = (a*a)%c; } return z; }
这个函数的写法就是二分法而已,但是刚开始时我写的是这样的
long long F(long long a, long long b, long long m) { if(b==1) return a%m; else if(b%2==0) return (F(a,b/2,m)*F(a,b/2,m))%m; else return (F(a,b/2,m)*F(a,b/2,m)*a%m); }
这样写的结果是RE,估计是递归太深导致堆栈溢出了,这个写的很差,根本没有起到二分的效果,反而比O(n)还要费时间。