time limit: 1 sec memory limit: 162 mb
submit: 5632 solved: 2356
[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
分析:ac自動機+dp.
首先把trie樹建出來.對問題做乙個轉化:求滿足要求的文章=總文章數-不滿足要求的文章數.那麼統計不滿足要求的文章數,也就是在trie上不能經過有結尾標記的點和fail指標指向的點有結尾標記的點,這是分別考慮單詞為字首和字尾的情況.
dp統計個數:f[i][j]表示文章的前i位匹配到trie樹的第j個節點的方案數. 先檢查j是否符合條件,然後轉移:f[i][e[j].tr[k]] += f[i-1][j].最後統計f[m][i]就是不滿足要求的文章數.
第一次做這類ac自動機上dp的題,trie樹上的節點也可以當做狀態!
#include #include#include
#include
#include
using
namespace
std;
const
int mod = 10007
;int n,m,tot = 1,f[110][6005
],ans1,ans2;
char s[110
];struct
node
}e[6010
];void
insert()
u =e[u].tr[x];
}e[u].isend = 1;}
void
build_fail()
else
e[u].tr[i] =e[fail].tr[i];}}
}int qpow(int a,int
b)
return
res;
}int
main()
build_fail();
f[0][1] = 1
;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= tot; j++)
}ans1 = qpow(26
,m);
for (int i = 1; i <= tot; i++)
if (!e[i].isend)
ans2 = (ans2 + f[m][i]) %mod;
printf(
"%d\n
",(ans1 - ans2 + mod) %mod);
return0;
}
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...