1. 程式人生 > >【期望+矩陣乘法】LOJ2325 [清華集訓 2017] 小 Y 和恐怖的奴隸主

【期望+矩陣乘法】LOJ2325 [清華集訓 2017] 小 Y 和恐怖的奴隸主

【題目】
原題地址
BOSS \text{BOSS} 初始有一個 m m 點生命值的奴隸主,它隨從上限是 K

K ,你會進行 n n 次攻擊,求期望 BOSS \text{BOSS} 扣多少血, T
T
組資料,每組資料 m , k m,k 相等。 T 1000
m 3 , K 8 , n 1 0 18 T\leq 1000 m\leq 3,K\leq 8,n\leq 10^{18}

爐宗賽高!
【解題思路】
首先發現這個 n n 很大,估計是個矩乘,這個 k k m m 很小,估計是個狀壓,於是思路就確定了。

接下來發現我們只關心剩餘 1 , 2 , 3 1,2,3 血的奴隸主各有多少個,我們可以考慮用期望的定義來求。那麼設 f i , j , k , l f_{i,j,k,l} 表示第 i i 輪時,剩餘 1 , 2 , 3 1,2,3 血量的奴隸主分別是 j , k , l j,k,l 個,那麼這個的答案貢獻就是 f i , j , k , l j + k + l + 1 \frac {f_{i,j,k,l}} {j+k+l+1}

我們打表可以知道狀態數為 i = 0 k C i + m 1 m 1 \sum\limits_{i=0}^kC_{i+m-1}^{m-1} ,加上統計答案的計數器一共只有166種,這樣每組資料暴力做 O ( T S 3 log n ) O(TS^3\log n) ,並不能過。觀察到轉移矩陣是一樣的,於是我們預處理出 2 k 2^k 的矩陣,這樣複雜度就是 O ( S 3 log n + T S 2 log n ) O(S^3\log n+TS^2\log n)

算起來還是十分卡卡卡卡常。

【參考程式碼】

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

typedef long long ll;
const int N=10,S=170,mod=998244353;
int T,m,K,tot;
int f[N][N],g[N][N][N];
ll n,ans[S],t[S];

ll read()
{
	ll ret=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
	return ret;
}
ll qpow(ll x,ll y){ll res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res;}

struct Matrix
{
	ll v[S][S];
	void clear(){memset(v,0,sizeof(v));}
	void one(){for(int i=0;i<S;++i)v[i][i]=1;}
	Matrix operator * (const Matrix&a)const
	{
		Matrix res;res.clear();
		for(int i=1;i<=tot;++i) for(int j=1;j<=tot;++j) for(int k=1;k<=tot;++k)
			res.v[i][j]=(res.v[i][j]+v[i][k]*a.v[k][j])%mod;
		return res;
	}
}A[60];
void mul(ll *a,const Matrix&b)
{
	memset(t,0,sizeof(t));
	for(int i=1;i<=tot;++i) for(int j=1;j<=tot;++j)
		t[j]=(t[j]+a[i]*b.v[i][j])%mod;
	for(int i=1;i<=tot;++i) a[i]=t[i];
}
void init1(){tot=3;A[0].v[3][1]=A[0].v[3][2]=A[0].v[3][3]=qpow(2,mod-2);}
void init2()
{
	for(int i=0;i<=K;++i) for(int j=0;j<=K;++j) 
		if(i+j<=K) f[i][j]=++tot;
	for(int i=0;i<=K;++i) for(int j=0;j<=K;++j) if(i+j<=K)
	{
		ll inv=qpow(i+j+1,mod-2);
		A[0].v[f[i][j]][1]=A[0].v[f[i][j]][f[i][j]]=inv;
		if(i) A[0].v[f[i][j]][f[i-1][j]]=inv*i%mod;
		if(j) 
		{
			if(i+j<K) A[0].v[f[i][j]][f[i+1][j]]=inv*j%mod;
			else A[0].v[f[i][j]][f[i+1][j-1]]=inv*j%mod;
		}
	}
}
void init3()
{
	for(int i=0;i<=K;++i) for(int j=0;j<=K;++j) for(int k=0;k<=K;++k)
		if(i+j+k<=K) g[i][j][k]=++tot;
	for(int i=0;i<=K;++i) for(int j=0;j<=K;++j) for(int k=0;k<=K;++k) if(i+j+k<=K)
	{
		ll inv=qpow(i+j+k+1,mod-2);
		A[0].v[g[i][j][k]][1]=A[0].v[g[i][j][k]][g[i][j][k]]=inv;
		if(i) A[0].v[g[i][j][k]][g[i-1][j][k]]=inv*i%mod;
		if(j)
		{
			if(i+j+k<K) A[0].v[g[i][j][k]][g[i+1][j-1][k+1]]=inv*j%mod;
			else A[0].v[g[i][j][k]][g[i+1][j-1][k]]=inv*j%mod;
		}
		if(k)
		{
			if(i+j+k<K) A[0].v[g[i][j][k]][g[i][j+1][k]]=inv*k%mod;
			else A[0].v[g[i][j][k]][g[i][j+1][k-1]]=inv*k%mod;
		}
	}
}
void solve()
{
	for(int i=1;i<60;++i) A[i]=A[i-1]*A[i-1];
	while(T--)
	{
		n=read();memset(ans,0,sizeof(ans));ans[3]=1;
		for(int i=0;i<60;++i) if(n&((ll)1<<i)) mul(ans,A[i]);
		printf("%lld\n"
            
           

相關推薦

期望+矩陣乘法LOJ2325 [清華集訓 2017] Y 恐怖奴隸主

【題目】 原題地址 BOSS \text{BOSS} BOSS初始有一個

[UOJ#340][清華集訓2017] Y 恐怖奴隸主期望 DP + 矩陣乘法

Address 洛谷P4007 UOJ#340 LOJ#2325 Solution 難道 m m

UOJ#340清華集訓2017 Y 恐怖奴隸主矩陣快速冪,動態規劃)

【UOJ#340】【清華集訓2017】小 Y 和恐怖的奴隸主(矩陣快速冪,動態規劃) 題面 UOJ 洛谷 題解 考慮如何暴力\(dp\)。 設\(f[i][a][b][c]\)表示當前到了第\(i\)次攻擊,還剩下的\(1,2,3\)血的奴隸主個數為\(a,b,c\)的概率,每次考慮打到了哪裡,做一個

LOJ2325清華集訓 2017Y恐怖奴隸主期望概率+矩陣快速冪)

LOJ2325「清華集訓 2017」小Y和恐怖的奴隸主 題意: "A fight? Count me in!" 要打架了,算我一個。 "Everyone, get in here!" 所有人,都過來! 小Y是一個喜歡玩遊戲的OIer。一天,她正在

LOJ2322清華集訓 2017」Hello world!

【題目連結】 點選開啟連結 【思路要點】 一個 1

LOJ2328清華集訓 2017」避難所

【題目連結】 點選開啟連結 【思路要點】 令 x

LOJ2326清華集訓 2017」簡單資料結構

【題目連結】 點選開啟連結 【思路要點】 注意到答案是 O

LOJ2323清華集訓 2017 Y 地鐵

【題目連結】 點選開啟連結 【思路要點】 很不錯的腦洞題。 附上官方題解。 時間複雜度 O

LOJ2324清華集訓 2017 Y 二叉樹

【題目連結】 點選開啟連結 【思路要點】 答案的第一位一定是編號最小的度數不為 3

LOJ2329清華集訓 2017」我的生命已如風中殘燭

【題目連結】 點選開啟連結 【思路要點】 一個直觀的思路是模擬該過程,當路上遇到環的時候通過類似取模的手段加速。 注意到每繞一個環

LOJ2331清華集訓 2017」某位歌姬的故事

【題目連結】 點選開啟連結 【思路要點】 注意到若一個位置被兩種音高 a

LOJ2330清華集訓 2017」榕樹之心

【題目連結】 點選開啟連結 【思路要點】 首先,樹是二分圖,只有一側的點可能成為心。 維護每一棵子樹會產生的向下推動的次數可能的最大值

LOJ2327清華集訓 2017」福若格斯

【題目連結】 點選開啟連結 【思路要點】 M

LOJ2320清華集訓 2017」生成樹計數

【題目連結】【思路要點】連上\(a_i\)的限制,題目要求的實際上是\(\sum_{T}\prod_{i=1}^{N}a_i^{d_i}*d_i^{M}\sum_{i=1}^{N}d_i^{M}\)。我們知道樹的Prufer序列與樹點的度數密切相關,因此考慮使用Prufer序

LOJ2321清華集訓 2017」無限之環

【題目連結】 【思路要點】 先說這道題的正解: 將棋盤看做一張二分圖,每一條邊拆成兩個點,分別屬於二分圖的一邊。 我們需要做一件類似於匹配的事情,同一條邊的兩側或是都沒有管道,或是都有管道。 通過合適的建邊我們能夠用最小費用最大流來解決本題。 時間複雜度

矩陣乘法CDOJ1610 黑紅梅方

ios tdi using long spa iostream for fin opera 考慮用4^n-不存在連續4個相同的。 f(i,j,k,l)表示以i為結尾的序列,最後三位分別是j,k,l時的方案。 可以轉移,寫一個64*64的轉移矩陣。 貌似可以優化?……未完待續

矩陣乘法OpenJ_POJ - C17F - A Simple Math Problem

() sign pri space con class std name per 算(7+4*sqrt(3))^n的整數部分(mod 1e9+7)。 容易想到矩乘快速冪,但是怎麽算整數部分呢? (7+4*sqrt(3))^n一定可以寫成a+b*sqrt(3),同理(7-4*

矩陣乘法Gym - 101412C - One-Dimensional Cellular Automaton

lar pac pen cnblogs int tor auto while images 給你一個一維細胞自動機,第i個格子在時刻t的狀態是這樣獲得的,問你t時刻的狀態。 把0時刻的狀態視作一個列向量,發現狀態轉移其實是一個n*n的矩陣(以n=5為例), B C

LOJ#2320. 「清華集訓 2017」生成樹計數

rac res 然而 除了 加法 wap OS 代碼 reg 題解 我,理解題解,用了一天 我,卡常數,又用了一天 到了最後,我才發現,我有個加法取模,寫的是while(c >= MOD) c -= MOD 我把while改成if,時間,少了 六倍。 六倍。 六倍!!

清華集訓Y地鐵

減少 樹狀 時間 系統 nbsp 數組 技術 image 比較 題目: 小 $\rm Y$ 是一個愛好旅行的 $\rm OIer$。一天,她來到了一個新的城市。由於不熟悉那裏的交通系統,她選擇了坐地鐵。她發現每條地鐵線路可以看成平面上的一條曲線,不同線路的交點處一定會設有換