题解:qoj 9479
Danslapiscine · · 题解
因为限制长成了环形的鬼样子,导致一个一个数地填维护限制非常困难,必须将填的过程对每个数同时进行。但是注意到
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
struct Matrix {
int a[3][3];
}I, ori, trans;
Matrix operator *(const Matrix &a,const Matrix &b){
Matrix ret;
for(int i=0;i<=2;i++) for(int j=0;j<=2;j++){
ret.a[i][j] = 0;
for(int k=0;k<=2;k++) ret.a[i][j] = (ret.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;
}
return ret;
}
Matrix ksm(Matrix s,int cnt){
Matrix ret = I;
while(cnt){
if(cnt & 1) ret = ret * s;
s = s * s;
cnt >>= 1;
}
return ret;
}
int N, M, S;
map<int,int> f;
int dfs(int M){
if(f.find(M) != f.end()) return f[M];
if(M == 0) return 1;
if(M == 1) return S;
int s;
if(M & 1) s = 1ll * dfs((M-1)/2) * S % mod;
else s = (1ll * dfs(M/2) + dfs(M/2-1)) % mod;
f[M] = s;
return s;
}
int main(){
I.a[0][0] = 1, I.a[1][1] = 1, I.a[2][2] = 1;
trans.a[1][0] = 1, trans.a[2][1] = 1, trans.a[0][2] = 1, trans.a[1][2] = 1;
ori.a[0][2] = 1;
scanf("%d%d",&N,&M);
ori = ori * ksm(trans, N-3);
S = ori.a[0][2];
ori = ori * trans;
S = (1ll * S + ori.a[0][2] + ori.a[0][1]) % mod;
ori = ori * trans;
S = (1ll * S + ori.a[0][1] + ori.a[0][0]) % mod;
printf("%d\n",dfs(M));
return 0;
}