。。估計大多數人都是看題推式子。。然後各種碼逆元。。
最後看到題解,就各種憋住的**破口而出。。
其實題目就是求
顯然有
這,這
【代碼】
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <bitset>
#define N 100005
#define mod 1000000007
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,Mod,k,r;
class Matrix{
public:
int v[55][55];
int x,y;
}a,b;
Matrix operator *(Matrix A,Matrix B){
Matrix rtn;rtn.x=A.x,rtn.y=B.y;
for(int i=1;i<=A.x;i++)
for(int j=1;j<=B.y;j++)
{
rtn.v[i][j]=0;
for(int k=1;k<=A.y;k++)
rtn.v[i][j]=(rtn.v[i][j]+1LL*A.v[i][k]*B.v[k][j]%Mod)%Mod;
}
return rtn;
}
Matrix Qpow(Matrix X,ll Y)
{
Matrix rtn;rtn.x=rtn.y=k;
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++) rtn.v[i][j]=(i==j)?1:0;
while(Y) {
if(Y&1) rtn=rtn*X;
X=X*X;Y>>=1;
}
return rtn;
}
int Ksm(int x,ll y){
int rtn=1;
while(y) {
if(y&1) rtn=1LL*x*rtn%Mod;
x=1LL*x*x%Mod;y>>=1;
}
return rtn;
}
int main()
{
n=read(),Mod=read(),k=read(),r=read();
if(k==1) {
printf("%d\n",Ksm(2,n));
return 0;
}
a.v[1][1]=1;a.x=1,a.y=b.x=b.y=k;
for(int i=1;i<=k;i++)
{
b.v[i][i]=1;
if(i!=1) b.v[i][i-1]=1;
else b.v[i][k]=1;
}
b=Qpow(b,1LL*n*k);
a=a*b;
printf("%d\n",a.v[1][r+1]);
return 0;
}