bzoj 2553 禁忌 AC自動機 期望DP

2021-07-30 14:04:19 字數 1274 閱讀 7255

先考慮乙個串a如何劃分價值最大,只需要按照所有t串在a中匹配的右端點排個序貪心去選,也就是希望我在a中匹配i個禁忌串,最靠後的右端點應該盡量靠前。

在ac自動機上對應為:只要走到乙個禁忌串的終止節點,就將它劃分出一段,(這裡的終止節點包括那些順著fail指標能走到終止節點的點)。

可以設dp[ i ][ j ]為在ac自動機上走了i步,走到了j節點的概率。

dp[ i ] [ ch[j][k] ] += dp[ i-1 ][ j ]*(1/alphabet);

dp[ i ] [ root ] += dp[ i-1 ][ j ]*1 ;(若果 j 是t串的終止節點)。

答案應該怎樣統計,可以新建乙個節點n,每當向root轉移時,也同樣向n點轉移,最後 dp[ len ][ n ]即為答案。

可以用矩陣乘法優化。

#include

#include

#include

#include

#include

#define maxn 105

#define flt long double

using

namespace

std;

char s[maxn];

int k,n;

struct mat

}};mat zero;

mat* operator *(mat &a,mat &b)

mat a,ans;

void

pow(int y)

}struct trie

val[p]=1;

}queue

q;void build()

q.push(u);

int p=fail[r];

while(p&&!ch[p][i]) p=fail[p];

fail[u]=ch[p][i];

val[u]|=val[fail[u]];}}

}void get_mat()

else a.a[i][u]+=x;}}

a.a[n][n]=1;

}}ac;

mat b;

int main()

ac.build();

ac.get_mat();

b.a[0][0]=1;

pow(len);

b=*(b*ans);

double q=b.a[0][n];

printf("%.9lf",q);

return

0;}

bzoj2553 禁忌 AC自動機 矩陣乘法

題目敘述比較煩。一句話,在字母只有前alphabet時,給定n個串,求長度為len的串包含這些n個串的個數最大值的期望值。觀察資料發現串的總長度 75,所以想到ac自動機 而len大小為10 9級別,就知道肯定是在ac自動機上的矩陣乘法,這樣大致的框架就好了。如果令a k x y 表示經過k步從狀態...

BZOJ 禁忌 AC自動機 概率DP 矩陣乘

magic land 上的人們總是提起那個傳說 他們的祖先 john 在那個東方島嶼幫助 koishi 與其姐姐 satori 最終戰平。而後,koishi 恢復了讀心的能力 如今,在 john 已經成為傳說的時代,再次造訪那座島嶼的人們卻發現 koishi 遇到了新麻煩。這次她遇到了 flandr...

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...