jsoi交給隊員zyx乙個任務,編制乙個稱之為「文字生成器」的電腦軟體:該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v6版。該軟體可以隨機生成一些文章―――總是生成一篇長度固定且完全隨機的文章—— 也就是說,生成的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們了解的乙個單詞,那麼我們說這篇文章是可讀的(我們稱文章a包含單詞b,當且僅當單詞b是文章a的子串)。但是,即使按照這樣的標準,使用者現在使用的gw文字生成器v6版所生成的文章也是幾乎完全不可讀的?。zyx需要指出gw文字生成器 v6生成的所有文字中可讀文字的數量,以便能夠成功獲得v7更新版。你能幫助他嗎?
輸入檔案的第一行包含兩個正整數,分別是使用者了解的單詞總數n (<= 60),gw文字生成器 v6生成的文字固定長度m;以下n行,每一行包含乙個使用者了解的單詞。這裡所有單詞及文字的長度不會超過100,並且只可能包含英文大寫字母a..z
乙個整數,表示可能的文章總數。只需要知道結果模10007的值。
2 2a
b100
給定n個模板串,求出至少包含1個模板串的長度為m的串的個數。
乍一看和dna sequence非常相似。但發現這題裡模板串較多較長,所以無法用矩陣快速次冪的方法解決。但是這題的要求構造的文字串長度較小,考慮動態規劃。
考慮求出所有不包含任何模板串的文字串的個數,再用總數減去。
用ac自動機構造出所有的邊。 設f
[i][
j]為走了i步到j點的方案總數。那麼f[
i][j
] 顯然可以轉移到f[
i+1]
[ch[
j][k
]],那麼初始化f[
0][0
]=1 ,按照順序dp即可。
答案即為26m
−σf[
m][i
] 。
#include
#include
#include
using namespace std;
const int max_size = 6000 + 10, ch_size = 26, mod = 10007, m = 100 + 10;
char s[m];
int n, m, d[m][max_size], ans;
struct trie
void insert(char *s)
val[u] = 1;
}void get_fail()
}while(l < r)
q[r++] = u;
int v = f[t];
while(v && !ch[v][i]) v = f[v];
f[u] = ch[f[t]][i];}}
}void solve()
}int tot1 = 1, tot2 = 0;;
for(int i = 1; i <= m; i++) tot1 = (tot1 * 26) % mod;
for(int i = 0; i < sz; i++) if(!val[i]) tot2 = (tot2 + d[m][i]) % mod;
ans = (tot1 - tot2 + mod) % mod;
}}ac;
void init()
}void work()
int main()
BZOJ1030 JSOI2007文字生成器
比起前面hnoi的gt考試,貌似這題是多模式串。然後我滾去學ac自動機了。發現還是很好寫的。ac自動機部分見筆記 搞出自動機之後,f i j 表示自動機上第i個節點匹配到第j個字元不可讀文字的數量,然後自己yy一下轉移 include include include define n 10005 d...
bzoj1030 JSOI2007 文字生成器
傳送門 思路 直接算好像比較困難,所以考慮先算不可讀的串的個數,再拿總串數去減。不可讀的串的數量就是在ac自動機上走m步而不經過結尾節點 包括結尾點和fail指向結尾點的節點 的路徑條數。這個怎麼求呢?設f i j 表示走i步,現在在j號節點的路徑條數。那麼f i j 可以轉移f i 1 son j...
bzoj1030 JSOI2007 文字生成器
time limit 1 sec memory limit 162 mb submit 2891 solved 1193 submit status discuss jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體 該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v...