ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[JSOI2007]文本生成器【AC自动机+DP】

2022-08-23 01:31:00  阅读:245  来源: 互联网

标签:AC ch JSOI2007 int 生成器 26 long ans fail


下定决心想要将这份爱意传达给你,与你在一起的每一刻总是那么值得珍藏,
你的存在左右着我的思绪,实在是不想错过这样的美好,
真的不和我在一起吗?
image

我的学术生涯,虽然有点奇妙,嗯,果然是开始了。导师是个副教授,叫我写\(vue\),嗯,也没问题,除了我一点也不会写\(vue\)之外。我从知网上下载他所有的论文时,忽然灵魂出窍灵光一现,想到一个海王见了都傻眼的点子。我的想法很大胆,我最近一直很大胆,不是不怕失败,不怕闯祸,不怕颜面尽失……只是,我渐渐明白了,只有肯在泥潭里打滚的野猪才能找到橡果。明天的任务就清晰了,一是学习\(vue\),二是研读手上的论文,三,最重要的,要给那几位教授发邮件轰炸了。我能预见我费心费力写的邮件可能被本校老师当做笑柄谈资,可能被外校老师一键删除,可是,我能预见,再也没有什么能阻止我了,就像我在开学前就加入\(ACM\)校队,就像我在军训前夕跌跌撞撞求加项目,就像我到武汉后就没有吃上一顿午饭,就像这个凌晨两点睡六点五十起床的日常……看吧,没有什么能阻止我。至于算法竞赛,我发现不觉间已更接近于深夜一种消遣了吧,就像春梦中的呓语。主动去追逐缥缈幻影里的鸿光吧,犯错的成本会越来越高的。标记好每个串的结尾点,跑AC自动机上按长度和节点方向\(DP\),求出不合法的情况数后容斥即可。

$click$ $for$ $codes$
# include "bits/stdc++.h"
using namespace std;
constexpr int N = 6003;
constexpr int mod = 1e4 + 7;
long long Pow(int x, int y) {
	long long ans = 1;
	for(; y; y >>= 1, x = 1ll * x * x % mod) if(y & 1) ans = ans * x % mod;
	return ans;
}
char str[N];
bool flag[N];
int ch[N][26], trie_index, fail[N];
struct Ahio_Corasick_Automation {
	void insert(char *str) {
		int len = strlen(str + 1), u = 0;
		for(int i = 1; i <= len; ++i) {
			int v = str[i] - 'A';
			if(!ch[u][v]) ch[u][v] = ++trie_index;
			u = ch[u][v];
		}
		flag[u] = true; // key 1
	}
	void build() {
		queue<int> q;
		for(int i = 0; i < 26; ++i) {
			if(ch[0][i]) {
				q.push(ch[0][i]);
			}
		}
		while(!q.empty()) {
			int u = q.front();
			q.pop();
			for(int i = 0; i < 26; ++i) {
				if(ch[u][i]) {
					fail[ch[u][i]] = ch[fail[u]][i];
					q.push(ch[u][i]);
					flag[ch[u][i]] |= flag[fail[ch[u][i]]]; // key 2
				} else {
					ch[u][i] = ch[fail[u]][i];
				}
			}
		}
	}
} AC;
long long f[N][N];
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		scanf("%s", str + 1);
		AC.insert(str);
	}
	AC.build();

	f[0][0] = 1; // key 3 // to assure length 1 -> val 1
	for(int i = 1; i <= m; ++i) {
		for(int j = 0; j <= trie_index; ++j) {
			if(flag[j]) continue;
			for(int k = 0; k < 26; ++k) {
				f[i][ch[j][k]] = (f[i][ch[j][k]] + f[i - 1][j]) % mod;
			}
		}
	}
	long long ans = Pow(26, m);
	for(int i = 0; i <= trie_index; ++i) {
		if(flag[i]) continue;
		ans = (ans - f[m][i] + mod) % mod;
	}
	printf("%lld", ans);
	return 0;
}

image

标签:AC,ch,JSOI2007,int,生成器,26,long,ans,fail
来源: https://www.cnblogs.com/bingoyes/p/16614777.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有