JSOI2007 文字生成器

2022-05-01 05:42:07 字數 1589 閱讀 4881

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 #include2

const

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...