time limit: 1 sec memory limit: 162 mb
submit: 2654 solved: 1100
[submit][status][discuss]
jsoi交給隊員zyx乙個任務,編制乙個稱之為「文字生成器」的電腦軟體:該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v6版。該軟體可以隨機生成一些文章―――總是生成一篇長度固定且完全隨機的文章—— 也就是說,生成的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們了解的乙個單詞,那麼我們說這篇文章是可讀的(我們稱文章a包含單詞b,當且僅當單詞b是文章a的子串)。但是,即使按照這樣的標準,使用者現在使用的gw文字生成器v6版所生成的文章也是幾乎完全不可讀的。 zyx需要指出gw文字生成器 v6生成的所有文字中可讀文字的數量,以便能夠成功獲得v7更新版。你能幫助他嗎?
輸入檔案的第一行包含兩個正整數,分別是使用者了解的單詞總數n (<= 60),gw文字生成器 v6生成的文字固定長度m;以下n行,每一行包含乙個使用者了解的單詞。 這裡所有單詞及文字的長度不會超過100,並且只可能包含英文大寫字母a..z 。
乙個整數,表示可能的文章總數。只需要知道結果模10007的值。
2 2a
b100
題意:給出n串字串ai(1<=i<=n<=60),問有多少種長度為m的字串至少包含乙個ai
分析:這種題很經典,就是ac自動機+dp,資料還很小,暴力dp即可
建出ac自動機後有兩種方法統計
1、dp[2][n][n*m](最多有n*m個節點)第一維表示是否訪問過危險節點(即是否包含ai)第二維表示這個長度為m的字串現在是第幾位,第三維表示當前在ac自動機上的第幾個節點dp[2][i][j]表示第i步走到第j個節點的方案數,最後統計答案即可
2、我的**是第二種方法的,求有多少種包含的,利用補集思想,即求總方案數-不包含的方案數,求不包含的方案數就是更加經典的ac自動機dp,dp[i][j]表示第i步走到第j個節點不碰到危險節點的方案數,總方案數顯然為26^m,相減即可
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #includeview code12 #include 13
using
namespace
std;
14 typedef long
long
ll;15 typedef double
db;16
#define for(i, s, t) for(int i = (s); i <= (t); i++)
17#define ford(i, s, t) for(int i = (s); i >= (t); i--)
18#define rep(i, t) for(int i = (0); i < (t); i++)
19#define repn(i, t) for(int i = ((t)-1); i >= (0); i--)
20#define rep(i, x, t) for(int i = (x); i < (t); i++)
21#define mit (2147483647)
22#define inf (1000000001)
23#define mll (1000000000000000001ll)
24#define sz(x) ((int) (x).size())
25#define clr(x, y) memset(x, y, sizeof(x))
26#define puf push_front
27#define pub push_back
28#define pof pop_front
29#define pob pop_back
30#define ft first
31#define sd second
32#define mk make_pair
33 inline void setio(string
name)
3940
const
int n = 70, m = 110, mod = 10007;41
struct
node tr[n*m];
45int
n, m, tot;
46int dp[m][n*m];
4748 inline void
input()
59 tr[x].danger = 1;60
}61}62
63 queueque;
64 inline void
build() 80}
81if(x) tr[x].danger |=tr[tr[x].fail].danger;82}
83}8485 inline void
solve() 96}
9798
int cnt = 0, sum = 1
, ans;
99 for(i, 0
, tot)
100if(!tr[i].danger) cnt = (cnt+dp[m][i])%mod;
101 rep(i, m) sum = (sum*26)%mod;
102 ans = (sum-cnt+mod)%mod;
103 printf("
%d\n
", ans);
104}
105106
intmain()
BZOJ1030 JSOI2007文字生成器
比起前面hnoi的gt考試,貌似這題是多模式串。然後我滾去學ac自動機了。發現還是很好寫的。ac自動機部分見筆記 搞出自動機之後,f i j 表示自動機上第i個節點匹配到第j個字元不可讀文字的數量,然後自己yy一下轉移 include include include define n 10005 d...
bzoj1030 JSOI2007 文字生成器
傳送門 思路 直接算好像比較困難,所以考慮先算不可讀的串的個數,再拿總串數去減。不可讀的串的數量就是在ac自動機上走m步而不經過結尾節點 包括結尾點和fail指向結尾點的節點 的路徑條數。這個怎麼求呢?設f i j 表示走i步,現在在j號節點的路徑條數。那麼f i j 可以轉移f i 1 son j...
bzoj1030 JSOI2007 文字生成器
time limit 1 sec memory limit 162 mb submit 2891 solved 1193 submit status discuss jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體 該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v...