- 题目描述
Icebound hates math. But Imp loves math. One day, Imp gave icebound a problem.
The problem is as follows.
For given q,n,p, you need to help icebound to calculate the value of S.
- 输入描述
The first line contains an integer T, denoting the number of test cases.
The next T lines, each line contains three integers q,n,p, separated by spaces.
- 输出描述
For each test case, you need to output a single line with the integer S.
- 样例输入
2
2 3 100
511 4 520
- 样例输出
14
184
- 题意
题意很简单,就是求等比数列前n项和%p,q是首项和公比,n是项数
- 思路
设等比数列第n项为Sn,第n-1项为Sn-1,则第n项与第n-1项之间存在线性关系:Sn = Sn-1 + a1 * q ^ (n - 1),符合矩阵快速幂的模板,其初始矩阵为:
1 1
0 q
对此矩阵执行快速幂即可,如果不会矩阵快速幂的请点击矩阵快速幂详解
-
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod;
struct node{
ll a[2][2];
};
node arr(node y, node z){
node x;
memset(x.a, 0, sizeof(x.a));
for(int i = 0; i < 2; i++)
for(int k = 0; k < 2; k++)
for(int j = 0; j < 2; j++)
x.a[i][j] = (x.a[i][j] + y.a[i][k] * z.a[k][j]) % mod;
return x;
}
node quick(node base, ll n){
node x;
memset(x.a, 0, sizeof(x.a));
x.a[0][0] = 1;
x.a[1][1] = 1;
while(n){
if(n & 1) x = arr(x, base);
base = arr(base, base);
n >>= 1;
}
return x;
}
int main(){
ll t;
scanf("%lld", &t);
while(t--){
ll q, n, p;
scanf("%lld%lld%lld", &q, &n, &p);
mod = p;
node x, y;
y.a[0][0] = 1;
y.a[0][1] = 1;
y.a[1][0] = 0;
y.a[1][1] = q;
x = quick(y, n - 1);
printf("%lld\n", ((x.a[0][0] * q) % mod + ((q * q) % mod *x.a[0][1]) % mod) % mod);
}
return 0;
}