题解:P9777 [HUSTFC 2023] Fujisaki 讨厌数学
Nuclear_Fish_cyq · · 题解
首先看眼式子。
关于这个式子的递推有一个很常用的技巧。我们考虑平方这个式子:
不对,这是什么???递推式,系数与
这不矩阵快速幂吗。然后问题就变成了矩阵咋推。
我们考虑矩阵
一列一列的填。第一列,我们有
然后写个矩阵快速幂。注意
代码:
#include <bits/stdc++.h>
#define ll long long
#define db double
#define ull unsigned long long
#define inf INT_MAX
#define linf LLONG_MAX
#define ninf INT_MIN
#define nlinf LLONG_MIN
#define mod m
#define lwbd lower_bound
#define upbd upper_bound
//#define range
using namespace std;
void read(int &x){
cin >> x;
return;
}
void readll(ll &x){
cin >> x;
return;
}void readdb(db &x){
cin >> x;
return;
}
ll n, m, a;
struct matrix{
ll col, row;
ll mat[100][100];
matrix(ll x, ll y){
col = y;
row = x;
for(int i = 0; i < x; i++){
for(int j = 0; j < y; j++){
mat[i][j] = 0;
}
}
}
matrix operator *(matrix p){
matrix res(row, p.col);
for(int i = 0; i < res.row; i++){
for(int j = 0; j < res.col; j++){
for(int k = 0; k < col; k++){
res.mat[i][j] += mat[i][k] * p.mat[k][j] % mod;
res.mat[i][j] %= mod;
}
}
}
return res;
}
matrix operator +(matrix p){
matrix res(row, col);
for(int i = 0; i < res.row; i++){
for(int j = 0; j < res.col; i++){
res.mat[i][j] = mat[i][j] + p.mat[i][j];
res.mat[i][j] %= mod;
}
}
return res;
}
matrix unit(ll x){
matrix p(x, x);
for(int i = 0; i < x; i++){
p.mat[i][i] = 1;
}
return p;
}
};
matrix qpow(matrix p, ll q){
if(q == 0){
return p.unit(p.col);
}
if(q == 1){
return p;
}
matrix res = qpow(p, q / 2);
if(q % 2){
return res * res * p;
}
return res * res;
}
//如果再忘记把题目给的1~n变为0~n-1自罚20仰卧起坐
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> m >> a >> n;
if(n == 0){
cout << 2 << endl;
}
if(n == 1){
cout << a % mod << endl;
}
if(n == 2){
cout << (a * a - 2) % mod << endl;
}
if(n < 3){
return 0;
}
matrix p(2, 2), q(1, 2);
q.mat[0][0] = (a * a - 2) % mod;
q.mat[0][1] = a;
p.mat[0][0] = a;
p.mat[0][1] = 1;
p.mat[1][0] = m - 1;
matrix ans = q * qpow(p, n - 2);
cout << ans.mat[0][0] << endl;
return 0;
}