ICode9

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

【YBTOJ】【Luogu P3966】[TJOI2013]单词

2021-06-01 13:34:46  阅读:217  来源: 互联网

标签:P3966 int YBTOJ pop TJOI2013 while fail 单词 getchar


链接:

洛谷

题目大意:

求每个单词分别在论文中出现了多少次。

正文:

对于整篇“论文”,也就是文本串,其实就是各个“单词”,即模式串,连接而成,而且有分隔符。

那么接下来就与二次加强的 AC 自动机板子一模一样了:因为直接跳失配指针会被卡,所以建 fail 树,然后跑 DFS 或者拓扑。

代码:

const int N = 3e6 + 10, M = 160;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n; 

namespace AC
{
	int t[N][30], id[N], val[N], cnt[N], fail[N];
	int tot;
	void Insert(char *s, int I)
	{
		int p = 0, len = strlen(s);
		for (int i = 0; i < len; i++)
		{
			int ch = s[i] - 'a';
			if (!t[p][ch]) t[p][ch] = ++tot;
			p = t[p][ch];
		}
		id[I] = p;
	}
	queue <int> q;
	vector <int> e[N];
	void Build()
	{
		while(!q.empty()) q.pop();
		for (int i = 0; i < 26; i++)
			if (t[0][i]) q.push(t[0][i]);
		while (!q.empty())
		{
			int p = q.front(); q.pop();
			for (int i = 0; i < 26; i++)
				if (t[p][i])
					fail[t[p][i]] = t[fail[p]][i], q.push(t[p][i]);
				else
					t[p][i] = t[fail[p]][i];
		}
		for (int i = 1; i <= tot; i++)
			e[fail[i]].push_back(i);
	}
	void Query(char *s)
	{
		int p = 0, ans = 0, len = strlen(s);
		for (int i = 0; i < len; i++)
		{
			p = t[p][s[i] - 'a'];
			val[p]++;
		}
	}
	void DFS(int u)
	{
		for (int i = 0, v; i < e[u].size(); i++)
			DFS(v = e[u][i]), val[u] += val[v];
	}
}

char s[N], t[N]; 

int main()
{
	n = Read();
	for (int i = 1; i <= n; i++)
		scanf ("%s", s), AC::Insert(s, i), strcat(t, s), strcat(t, "@");
	AC::Build();
//	puts(t);
	AC::Query(t);
	AC::DFS(0);
	for (int i = 1; i <= n; i++)
		printf ("%d\n", AC::val[AC::id[i]]);
	return 0;
}

标签:P3966,int,YBTOJ,pop,TJOI2013,while,fail,单词,getchar
来源: https://www.cnblogs.com/GJY-JURUO/p/14836796.html

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

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

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

ICode9版权所有