1. 程式人生 > 實用技巧 >【YbtOJ#20234】能量收集

【YbtOJ#20234】能量收集

題目

題目連結:https://www.ybtoj.com.cn/contest/66/problem/2

思路

\(f[i][j]\) 表示機器人到達橫座標為 \(i\) 的位置時,效率為 \(j\) 的期望。這個玩意很好轉移。
然後答案就是 \(nB+\sum^{n}_{i=1}\sum^{m}_{j=0}f[i][j]\times j\times A\)
然後矩陣乘法優化即可。開第 \(m+1\) 個點表示能量之和。
時間複雜度 \(O(m^3\log n)\)

程式碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll M=55,MOD=1e9+7,inv100=570000004;
ll n,m,A,B,x,y;

struct Matrix
{
	ll a[M][M];
	
	friend Matrix operator *(Matrix a,Matrix b)
	{
		Matrix c;
		memset(c.a,0,sizeof(c.a));
		for (ll i=0;i<=m+1;i++)
			for (ll j=0;j<=m+1;j++)
				for (ll k=0;k<=m+1;k++)
					c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%MOD;
		return c;
	}
}f,a;

int main()
{
	freopen("power.in","r",stdin);
	freopen("power.out","w",stdout);
	scanf("%lld%lld%lld%lld%lld%lld",&n,&A,&B,&m,&x,&y);
	x=x*inv100%MOD; y=y*inv100%MOD;
	f.a[1][0]=1;
	a.a[0][0]=1-x; a.a[0][1]=x;
	a.a[m][m]=1-y; a.a[m][m-1]=y;
	for (ll i=1;i<m;i++)
	{
		a.a[i][i-1]=y;
		a.a[i][i+1]=x;
		a.a[i][i]=(1-x-y)%MOD;
	}
	for (ll i=0;i<=m;i++)
		a.a[i][m+1]=A*i%MOD;
	a.a[m+1][m+1]=1;
	ll t=n+1;
	for (;t;t/=2LL,a=a*a)
		if (t%2LL==1LL) f=f*a;
	printf("%lld\n",((f.a[1][m+1]+n%MOD*B)%MOD+MOD)%MOD);
	return 0;
}