bzoj1030 JSOI2007 文字生成器

2022-05-18 06:15:57 字數 2801 閱讀 5445

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 #include 

12 #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()

view code

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