分析:ac自動機+dp。
正難則反,求滿足的,可以求出不滿足的,用總的減去。所以考慮如何就出所有的長度為m的串裡,沒有出現任何乙個單詞的個數。
建立ac自動機,然後會有一些點是一定不能走的,這些點要麼是某些單詞的結尾,或者是包含了某些單詞(以它結尾的串的字尾是乙個單詞)。
然後f[i][j]表示當前有i位,在ac自動機的第j個位置的方案數,即文字串中的字尾是ac自動機從0到這裡構成的串,那麼只要讓文字串不要走有標記的點就行了。列舉下一位是什麼,在ac自動機上轉移。(注意,可能有許多點有些字元沒有邊,那麼經過了這個字元也是合法的。這些的點貢獻也要算上。假設存在這個點,直接轉移即可。重新走到0號點的意義是當前和文字串的匹配長度為0)
**:
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #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...