题目分析:
构造f[nk][r]表示题目中要求的东西。容易发现递推公式f[nk][r]=f[nk-1][r]+f[nk-1][(r-1)%k].矩阵快速幂可以优化,时间复杂度O(k^3logn)。
代码:
#include<bits/stdc++.h>
using namespace std; int n,p,k,r; long long mat[][];
long long g[][];
long long t[][]; void fast_pow(long long pw){
if(pw == ) {
for(int i=;i<k;i++) for(int j=;j<k;j++) g[i][j] = mat[i][j];
return;
}
fast_pow(pw/);
for(int i=;i<k;i++) for(int j=;j<k;j++) t[i][j] = g[i][j];
memset(g,,sizeof(g));
for(int o=;o<k;o++){
for(int i=;i<k;i++){
for(int j=;j<k;j++){
g[i][j] += (t[i][o]*t[o][j])%p;
g[i][j] %= p;
}
}
}
if(pw&){
for(int i=;i<k;i++) for(int j=;j<k;j++) t[i][j] = g[i][j];
memset(g,,sizeof(g));
for(int o=;o<k;o++){
for(int i=;i<k;i++){
for(int j=;j<k;j++){
g[i][j] += (t[i][o]*mat[o][j])%p;
g[i][j] %= p;
}
}
}
}
} void BuildMat(){
for(int i=;i<k;i++){
mat[i][i] += ; mat[i][(i-+k)%k] += ;
}
} void work(){
BuildMat();
fast_pow(1ll*n*k);
printf("%lld",g[r][]);
} int main(){
scanf("%d%d%d%d",&n,&p,&k,&r);
work();
return ;
}