有 n
nn 個單詞,現在要生成 m
mm 個字母的文字,問至少出現乙個單詞的文字有多少種。
n ≤60
,m
≤100,∣
si∣≤
100n\leq 60,m\leq 100,|s_i|\leq 100
n≤60,m
≤100
,∣si
∣≤1
00s
is_i
si 只包含大寫英文本母。
這算是一道很典型的 acac
ac自動機上 dpdp
dp的題目。
答案就是用 26m
26^m
26m 減去乙個單詞都沒出現過的。現在我們求一下後面的東西。
令 f i,
jf_
fi,j
表示長度為 i
ii,來到節點 j
jj 的方案數。
那麼如果 trj
,k
tr_tr
j,k
不是末尾節點,就可以轉移到 trj
,k
tr_tr
j,k
。初始條件 f0,
0=
1f_=1
f0,0=
1。總複雜度是 o(26
n∣s∣
m)
o(26n|s|m)
o(26n∣
s∣m)
#include
#include
#include
using
namespace __gnu_pbds;
using
namespace std;
typedef
long
long ll;
typedef
unsigned
long
long ull;
struct custom_hash
size_t operator()
(uint64_t x)
const};
ll z =1;
intread()
intksm
(int a,
int b,
int p)
return s;
}const
int mod =
1e4+
7, n =
6e3+5;
int f[
105]
[n], ch[n][26
], fail[n]
, v[n]
, cnt;
char s[n]
;void
insert
(char
*s) v[p]=1
;}void
get_fail()
}}intmain()
get_fail()
; ans =
ksm(
26, m, mod)
; f[0]
[0]=
1;for(i =
0; i <= m; i++)}
}}for(i =
0; i <= cnt; i++
) ans =
(ans - f[m]
[i])
% mod;
printf
("%d"
,(ans + mod)
% mod)
;return0;
}
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...