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