对于式子的值,我们若直接算出等比数列的和再模上M,那么中间结果可能会溢出。对于这个问题,我们可以用二分求和来做,这样一来,它的中间结果每次都在模M,任何时候都不会有溢出的危险。对上述式子进行如下化简:
根据,以上化简的结果,我们可以得出递归的代码:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int MOD = 10000; 5 int Pow(int a, int n) 6 { 7 int r=1; 8 while(n) 9 { 10 if(n&1) 11 r = (r*a)%MOD; 12 a = (a*a)%MOD; 13 n >>= 1; 14 } 15 return r; 16 } 17 // 计算Sn = (a^1+a^2+...+a^n)%MOD 18 int Sum(int a, int n) 19 { 20 if(n==1) return a; 21 int t = Sum(a, n/2); 22 if(n&1) 23 { 24 int c = Pow(a, n/2+1); 25 t = (t%MOD+(t%MOD*c%MOD)%MOD+c%MOD)%MOD; 26 } 27 else 28 { 29 int c = Pow(a, n/2); 30 t = (t + t*c) % MOD; 31 } 32 return t; 33 } 34 int main() 35 { 36 int a, n; 37 while(~scanf("%d%d",&a, &n)) 38 { 39 printf("%d\n",Sum(a, n)); 40 } 41 return 0; 42 }