题解-[JSOI2007]文本生成器

该博客详细介绍了JSOI2007文本生成器问题的解决方案,涉及AC自动机和动态规划。首先构建AC自动机,通过fail指针解决模式串匹配。然后利用动态规划计算不含任何模式串的文本串数量,最终得到满足条件的文本串总数。推荐了相关学习题目。
摘要由CSDN通过智能技术生成

[JSOI2007]文本生成器

这题就是那种著名的AC自动机+dp题,算法唯一,如果你不会AC自动机,出门左转[传送门]

这题当中的那些单词就相当于AC自动机模板中的模式串,只不过这题当中是要求满足“包含至少一个模式串的”文本串而已。

所以先把模式串放到 trie \texttt{trie} trie 树上,然后用AC自动机的 build() \texttt{build()} build() 函数把 f a i l fail fail 指针构造出来,并把 c h [ ] [ ] ch[][] ch[][] 数组进化为一条永通路,以便避免文本串匹配时一个模式串到结尾了没有地方可走的尴尬。

以上都是对模板的解说。 对于这题,我们发现“包含至少一个”这样的约束条件,就想到 答案 = = =整体 − - 剩余,先求出一个模式串都不包含的文本串数,然后求出没有约束条件下文本串有 2 6 m 26^m 26m 种,就可以得出答案。

因为要求一个模式串都不包含的文本串数,所以 insert(s) \texttt{insert(s)} insert(s) 的时候在有字符串结尾的节点 x x x 上注 m k [ x ] = 1 mk[x]=1 mk[x]=1,如下:

void insert(char*s){
   
	int n=strlen(s+1),p=1;
	for(int i=1;i<=n;i++){
   
		int c=s[i]-'A'+1;
		if(!ch[p][c]) ch[p][c]=++cnt;
		p=ch[p][c];
	}
	mk[p]=1;
}

又因为如果一个字符串的后缀是模式串,那么它也不能出现在文本串中,所以在构造AC自动机 f a i l fail fail 指针的时候要令 m k [ x ] ∣ = m k [ f a i l

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值