# UOJ241(递推＋矩阵快速幂）

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;

const ll mod = 998244353;

mat mul(mat & A,mat & B){
mat C(A.size(),vec(B[0].size()));
for(int i = 0;i < (int) A.size();i++){
for(int k = 0;k < (int) B.size();k++) if(A[i][k] != 0){
for(int j = 0;j < (int)B[0].size();j++){
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod;
}
}
}
return C;
}

mat pow(mat A,ll n){
mat B(A.size(),vec(A.size()));
for(int i = 0;i < A.size();i++){
B[i][i] = 1;
}
while(n > 0){
if(n & 1) B = mul(B,A);
A = mul(A,A);
n >>= 1;
}
return B;
}

ll n,m;

int main(int argc, const char * argv[]) {
cin >> n >> m;
if(n & 1){
if(m == 1){
cout << 0 << endl;
return 0;
}
mat A(2,vec(2));
A[0][0] = (m - 2) % mod;
A[0][1] = (m - 1) % mod;
A[1][0] = 1;
A[1][1] = 0;
A = pow(A,n - 1);
ll ans = A[0][1] * m % mod;
cout << ans << endl;
}else{
if(m == 1){
cout << 0 << endl;
return 0;
}
if(n == 2){
cout << m * (m - 1) % mod << endl;
return 0;
}else{
if(m == 2){
if(n % 4 == 0){
cout << 0 << endl;
}else{
cout << 2 << endl;
}
return 0;
}
else{
mat A(9,vec(9));
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++){
A[i][j] = 0;
}
}
A[5][0] = 1;
A[5][6] = 1;
A[5][7] = 1;
A[5][1] = 1;
A[7][0] = 1;
A[7][2] = 1;
A[7][5] = 1;
A[7][3] = 1;
A[3][1] = (m - 2) % mod;
A[3][0] = (m - 3) % mod;
A[3][2] = (m - 2) % mod;
A[3][6] = (m - 3) % mod;
A[3][7] = (m - 2) % mod;
A[1][3] = (m - 2) % mod;
A[1][0] = (m - 3) % mod;
A[1][6] = (m - 2) % mod;
A[1][2] = (m - 3) % mod;
A[1][5] = (m - 2) % mod;
A[6][2] = (m - 2) % mod;
A[6][0] = (m - 3) % mod;
A[6][1] = (m - 2) % mod;
A[6][3] = (m - 3) % mod;
A[6][5] = (m - 2) % mod;
A[2][6] = (m - 2) % mod;
A[2][0] = (m - 3) % mod;
A[2][3] = (m - 2) % mod;
A[2][1] = (m - 3) % mod;
A[2][7] = (m - 2) % mod;
A[0][0] = ((m - 3) + (m == 3 ? 0 :(m - 4) * (m - 4))) % mod;
A[0][1] = (m - 3) * (m - 3) % mod;
A[0][2] = (m - 3) * (m - 3) % mod;
A[0][3] = (m - 3) * (m - 3) % mod;
A[0][5] = (m - 2) * (m - 3) % mod;
A[0][6] = (m - 3) * (m - 3) % mod;
A[0][7] = (m - 2) * (m - 3) % mod;
A = pow(A,n / 2 - 1);
ll ans = 0;
ans += (A[0][5] + A[2][5] + A[3][5] + A[5][5]) % mod;
ans = ans * m % mod * (m - 1) % mod;
cout << ans << endl;
}
}
}
return 0;
}

• 本文已收录于以下专栏：

## HDU 2604 Queuing (递推+ 矩阵快速幂)

Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total...

## NYOJ 1075 （递推 + 矩阵快速幂）

“红色病毒”问题 时间限制：1000 ms | 内存限制：65535 KB 难度：4 描述 医学研究者最近发现了一种新病毒，因为其蔓延速度与曾经在Internet上传播的“红色代码”不相上下，故被...

## HDU 2604 递推 + 矩阵快速幂

HDU 2604 题解:首先， 记长为n的队列的K队列数为f(n); 易求得:f(0) = 0, f(1) = 2, f(2) =  4, f(3) = 6, f(4) =...
• 2016-10-06 18:37
• 109

## HDU4565-So easy-数学推导化简递推矩阵快速幂

So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...

## hrbust 1375 The Active Leyni【暴力打表+递推+矩阵快速幂】

The Active Leyni Time Limit: 1000 MS Memory Limit: 65536 K   Total Submit: 111(43 ...

举报原因： 您举报文章：深度学习：神经网络中的前向传播和反向传播算法推导 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)