JSOI2007 文字生成器

2022-05-23 08:15:13 字數 934 閱讀 4318

傳送門

ac自動機+dp

直接從正面做

設\(f[i][j][0/1]\)表示在節點\(i\),串長為\(j\),是否已經經過結尾點的總方案數,然後從父親向兒子轉移

做\(dp\)的時候不用跳\(fail\),在構建\(fail\)指標的時候順帶把對於結尾點的標記通過\(fail\)指標擴充套件到它在\(fail\)樹上的祖先(不知道這樣理解對不對)

ps:大寫看成小寫調了1h……

放**

#includeusing namespace std;

const int n = 10000 + 10;

const int mod = 10007;

char s[n];

int n, m, ch[n][30], lst[n], fail[n], val[n], f[n][105][2], sz = 1, ans;

void insert(char *s) u = ch[u][c];

} val[u] = 1;

}void getfail() q.push(u);

int v = fail[r];

while (v && !ch[v][i]) v = fail[v];

fail[u] = ch[v][i];

val[u] |= val[fail[u]];

lst[u] = val[fail[u]] ? fail[u] : lst[fail[u]];

} }}void dp()

}}int main()

getfail();

dp();

for (register int i = 0; i < sz; ++i) ans = (ans + f[i][m][1]) % mod;

cout << ans;

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