1030 JSOI2007 文字生成器

2022-04-06 13:32:43 字數 1592 閱讀 8713

分析:ac自動機+dp。

正難則反,求滿足的,可以求出不滿足的,用總的減去。所以考慮如何就出所有的長度為m的串裡,沒有出現任何乙個單詞的個數。

建立ac自動機,然後會有一些點是一定不能走的,這些點要麼是某些單詞的結尾,或者是包含了某些單詞(以它結尾的串的字尾是乙個單詞)。

然後f[i][j]表示當前有i位,在ac自動機的第j個位置的方案數,即文字串中的字尾是ac自動機從0到這裡構成的串,那麼只要讓文字串不要走有標記的點就行了。列舉下一位是什麼,在ac自動機上轉移。(注意,可能有許多點有些字元沒有邊,那麼經過了這個字元也是合法的。這些的點貢獻也要算上。假設存在這個點,直接轉移即可。重新走到0號點的意義是當前和文字串的匹配長度為0)

**:

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11

#define fi(s) freopen(s,"r",stdin);

12#define fo(s) freopen(s,"w",stdout);

13using

namespace

std;

14 typedef long

long

ll;15

16 inline int

read()

2021

const

int n = 105;22

const

int c = 200005;23

const

int mod = 10007;24

25char

s[n];

26int f[n][c], ch[c][26

], val[c], fail[c], q[c], index, n, m;

2728

void insert(char *s)

35 val[u] = 1;36

}37void

build()

43while (l <=r)

50 q[++r] =v;

51int p =fail[u];

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

53 fail[v] =ch[p][c];

54 val[v] = val[v] ?val[v] : val[fail[v]];55}

56}57}

58void

dp() 66}

67}68}

69int

main()

75build();

76dp();

77int ans = 1;78

for (int i=1; i<=m; ++i) ans = (ans * 26) %mod;

79for (int j=0; j<=index; ++j)

80if (!val[j]) ans = (ans - f[m][j] + mod) %mod;

81 cout <82return0;

83 }

1030 JSOI2007 文字生成器

題目鏈結 題目大意 給出 n 個長度不超過 l 的字串,求有多少長度為 m 的字串 含有至少乙個之前給到的字串,字符集大小為 26 題解 至少1個提示我們使用補集轉化 總數明顯是26 m,現在計算有多少字串不含有任何乙個給出的字串 將給出字串建成ac自動機,然後標記所有結尾結點,及fail指標指向結...

1030 JSOI2007 文字生成器

jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體 該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v6版。該軟體可以隨機生成一些文章 總是生成一篇長度固定且完全隨機的文 章 也就是說,生成的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們了解的乙個單詞...

BZOJ1030 JSOI2007文字生成器

比起前面hnoi的gt考試,貌似這題是多模式串。然後我滾去學ac自動機了。發現還是很好寫的。ac自動機部分見筆記 搞出自動機之後,f i j 表示自動機上第i個節點匹配到第j個字元不可讀文字的數量,然後自己yy一下轉移 include include include define n 10005 d...