time limit: 1 sec memory limit: 162 mb
submit: 4962 solved: 2055
[submit][status][discuss]
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
思路先利用給出的單詞,構建乙個ac自動機,並在標記單詞結束的點;
因為可讀文章不好統計,所以統計不可讀文章;
f[i][j]表示i長度的到j節點結束的不可讀文章數量;
狀態轉移:f[i][next[j][k]]+=f[i-1][j];
**實現
1 #include2const
int mod=1e4+7;3
const
int maxn=1e2+1;4
const
int size=1e5+1;5
int n,m,ans=1
,now;
6int
f[maxn][size];
7int
q[size],head,tail;
8int next[size][26
],fail[size],sz;
9char
ch[maxn];
10bool
v[size];
11void
ins()
16 a=ch[i]-'a'
;17if(!next[j][a]) next[j][a]=++sz;
18 j=next[j][a];19}
20return;21
}22void
build()
35 q[tail++]=next[a][i];36}
37else next[a][i]=next[fail[a]][i];38}
39return;40
}41void
dp()50}
51}52for(int i=0;i<=sz;i++)
53if(!v[i])57}
58int
main()
JSOI2007 文字生成器
用ac自動機處理所有了解的單詞 顯然,不能直接算,直接算的話,我們需要大力容斥,複雜度不允許 我們不妨反過來做,我們根據ac自動機處理出所有的不可行解,然後用總數減去即可 計算所有不可行解用dp,f i j 表示處理到字串第i位,在自動機上第j個節點的不可行方案數,直接暴力轉移即可 include ...
JSOI2007 文字生成器
容斥原理,求出所有的情況減去不可讀的情況就是可讀的文字數了a 找不可讀文字的數量類似於病毒那一題趴我覺得 dp轉移的話.用f i j 表示當前在節點j,且串長為i時的情況 include using namespace std const int mod 1e4 7 const int n 2000...
JSOI2007 文字生成器
對於乙個長度為 n 的串 s 有多少可能情況的串 s 使得 s 的子串中至少包含乙個給定的串,給定的串有 m 個 由多模式串匹配想到ac自動機,由計數想到dp 首先建好trie圖,更新所有end標記。記 dp now st flag 表示當前正在匹配第 st 位,已確定的串匹配到了trie圖上的 n...