BZOJ 1030文字生成器

2021-09-25 22:37:59 字數 1387 閱讀 9525

第一次做ac自動機+dp的題。因為前日做過一道字串dp題,這題做起來相對沒那麼困難一些。覺得一時間這題無法下手可以先試試這場div3的f題:

題意:給你n個模式串,現在構造出m長度僅有26個字母的文字串,使其中至少包含1個模式串,問有多少個。

思路:很容易想到dp,dpij,i表示構造到第幾位,j來列舉ac自動機的狀態。在每個狀態列舉26個字母轉移到新狀態。不過在嘗試直接構造的情況下會發現,當構造出來乙個包含模式串的狀態時,轉移到下乙個狀態,並不知道在個狀態哪一部分是合法來的哪一部分是不合法的。所以可以利用補集,把到達合法狀態的篩掉,那麼達到最終狀態的dpmj累加起來取26^m的補集則是最終答案。

細節部分要注意:

當前面某乙個狀態的字尾或者說失配對應位置如果包含模式串,那麼剩下的也都得包含,所以預處篩掉,這裡我在build函式裡加了個if(cnt[fail[u]])cnt[u] = 1;如此一層一層往上會層層標記恰好達到效果。

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i=0;i#define for1(i,n) for(int i=1;i<=n;i++)

#define io ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

const

int maxn =

6e3+5;

const

int mod =

1e4+7;

int dp[

105]

[maxn]

,fail[maxn]

,trie[maxn][26

],id,cnt[maxn]

;class

aho cnt[u]++;

} queue<

int>q;

void

build()

}}}aho;

ll powmod

(ll a,ll b)

return res;

}int

main()

aho.

build()

; dp[0]

[0]=

1;forn

(i,m)}}

ll ans =

powmod(26

,m);

forn

(i,id+1)

if(!cnt[i]

)(ans=ans+mod-dp[m]

[i])

%=mod;

cout << ans <<

'\n'

;return0;

}

bzoj 1030 文字生成器

題意 給出乙個n個單詞的字典,單詞長度 100 求長度為m的隨機字串中有多少個串至少包括乙個單詞 n 60,m 100 題解 好久沒有寫ac自動機啦,如今還記得模板真是難得 然而這似乎是trie圖?總之寫出來不差幾句話 首先至少包括乙個單詞這個條件不太好弄 那就轉化一下,求不含單詞的字串個數 然後就...

BZOJ 1030 文字生成器

1030 jsoi2007 文字生成器 time limit 1 sec memory limit 162 mb submit 4777 solved 1986 submit status discuss description jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體...

bzoj1030 文字生成器

題目鏈結 給出 n 個字串,要構造乙個長度為 m 的字串 s 使得給出的 n 個字串中至少有乙個是 s 的子串。問方案數。ac 自動機 dp 考慮至少有乙個是s的子串不好考慮。考慮用全部情況減去其中不包含任何乙個字串的情況。全部情況就是 26 m 然後考慮怎麼求出不包含任何乙個字串的情況。用 f i...