JSOI2007 文字生成器

2022-07-06 21:24:11 字數 1521 閱讀 1450

description

jsoi 交給隊員 zyx 乙個任務,編制乙個稱之為「文字生成器」的電腦軟體:該軟體的使用者是一些低幼人群,他們現在使用的是 gw 文字生成器 v6 版。該軟體可以隨機生成一些文章――總是生成一篇長度固定且完全隨機的文章——也就是說,生成的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們了解的乙個單詞,那麼我們說這篇文章是可讀的(我們稱文章\(a\)包含單詞\(b\),當且僅當單詞\(b\)是文章\(a\)的子串)。

但是,即使按照這樣的標準,使用者現在使用的 gw 文字生成器 v6 版所生成的文章也是幾乎完全不可讀的。zyx 需要指出 gw 文字生成器 v6 生成的所有文字中可讀文字的數量,以便能夠成功獲得 v7 更新版。你能幫助他嗎?

input

輸入的第一行包含兩個正整數,分別是使用者了解的單詞總數\(n\),gw 文字生成器 v6 生成的文字固定長度\(m\);

以下\(n\)行,每一行包含乙個使用者了解的單詞。

output

乙個整數,表示可能的文章總數。只需要知道結果模\(10007\)的值。

sample input

2 2

ab

sample output
100
data constraint

對於全部資料\(1<=n<=60\),所有單詞及文字的長度不會超過100,並且只可能包含英文大寫字母。

solution

正難則反

1.建自動機

2.給可能經過單詞結尾的位置打上標記

3.設\(f[i][j]\)表示當前長度為\(j\),在自動機上第\(i\)個點的不合法方案數

4.\(ans=26^m-σf[i][m]\)

code

#includeusing namespace std;

#define f(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

#define mo 10007

#define n 70

#define l 110

#define p 6010

queueq;

int n,m,ans=1,sum,f[p][l],len;

char ch[l];

struct acm

void build()

fail[v]=son[fail][i];

flag[v]|=flag[u];

q.push(v);

}} f(i,1,he)flag[q[i]]|=flag[fail[q[i]]];//標記

}}t;

int main()

f(i,1,t.tot)(sum+=f[i][m])%=mo;//dp

f(i,1,m)(ans*=26)%=mo;

printf("%d",(ans-sum+mo)%mo);

return 0;

}

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