CCPC-Wannafly & Comet OJ 夏季歡樂賽(2019)

今天打了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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章