今天打了CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)
对退休老年党太友好了!码量小的惊人,且思路简单,瞎捏捏就粗来了。
鉴于太久没有更博了,我今天要更博!
感觉太久没打代码了,假期回去会被锤爆吧!我要趁工作之余悄悄代码,不能称为一条竞赛咸鱼!
E
可以推导出当位于前k格的时候,到达终点的期望都是一样的。
后面就可以直接用矩乘推出来了。
(在网上扒拉代码扒拉了好久……没板子实惨
#include<iostream>
#include<string.h>
#include<math.h>
#include<vector>
#include<algorithm>
#define ll long long
using namespace std;
const long long N=30;
const long long mod=1000000007;
long long tmp[N][N];
void multi(long long a[][N], long long b[][N], long long n){
memset(tmp,0,sizeof tmp);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%mod;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=tmp[i][j];
}
long long res[N][N];
void Pow(long long a[][N],long long n, long long size){
memset(res,0,sizeof (res) );//n是幂,N是矩阵大小
for(int i=0;i<size;i++) res[i][i]=1;
while(n){
if(n&1)
multi(res,a,size);//res=res*a;复制直接在multi里面实现了;
multi(a,a,size);//a=a*a
n>>=1;
}
}
void exgcd(ll a,ll b,ll& d,ll& x,ll& y)
{
if(!b) { d = a; x = 1; y = 0; }
else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }
}
ll inv(ll a, ll p)
{
ll d, x, y;
exgcd(a, p, d, x, y);
return d == 1 ? (x+p)%p : -1;
}
long long a[N][N];
int main(){
ll n,k;
cin>>n>>k;
for (int i=1;i<k;i++){
a[i][i-1]=1;
}
ll x=inv(k,mod);
for (int i=0;i<k;i++){
a[i][k-1]=x;
}
a[k][k-1]=a[k][k]=1;
/*
for (int i=0;i<k;i++){
for (int j=0;j<k;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
*/
Pow(a,n-1,k+1);
/*
for (int i=0;i<k+1;i++){
for (int j=0;j<k+1;j++){
cout<<res[i][j]<<" ";
}
cout<<endl;
}
*/
ll ans=0;
for (int i=0;i<k;i++){
ans=(ans+k*res[i][0])%mod;
}
ans=(ans+res[k][0])%mod;
cout<<ans<<endl;
}