ICode9

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

洛谷 P2292 [HNOI2004]L语言(AC自动机,dp)

2021-10-11 21:00:25  阅读:142  来源: 互联网

标签:AC 洛谷 int num HNOI2004 maxn include dp


传送门


解题思路

设dp[i]为先i位能否被理解。

然后在AC自动机上匹配,若 num[j]&&dp[i-cnt[j]] 则 dp[i] 等于 1。(j为不断fail的指针)

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int maxn=305;
const int maxm=2e6+5;
int tr[maxn][30],dp[maxm],cnt[maxn],tot,num[maxn],fail[maxn],n,m;
string s;
void insert(string s){
	int now=0,len=s.length();
	for(int i=0;i<len;i++){
		int k=s[i]-'a';
		if(!tr[now][k]) tr[now][k]=++tot;
		now=tr[now][k];
	}
	cnt[now]=len;
	num[now]++;
}
void build(){
	queue<int> q;
	for(int i=0;i<26;i++){
		if(tr[0][i]) q.push(tr[0][i]);
	}
	while(!q.empty()){
		int now=q.front();q.pop();
		for(int i=0;i<26;i++){
			if(tr[now][i]){
				fail[tr[now][i]]=tr[fail[now]][i];
				q.push(tr[now][i]);
			}else{
				tr[now][i]=tr[fail[now]][i];
			}
		}
	}
}
int query(string s){
	memset(dp,0,sizeof(dp));
	dp[0]=1;
	int now=0,len=s.length();
	for(int i=0;i<len;i++){
		now=tr[now][s[i]-'a'];
		for(int j=now;j;j=fail[j]){
			if(num[j]&&dp[i-cnt[j]+1]){
				dp[i+1]=1;
				break;
			}
		}
	}
	for(int i=len;i>=0;i--){
		if(dp[i]) return i;
	}
}
int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>s,insert(s);
	build();
	for(int i=1;i<=m;i++) cin>>s,cout<<query(s)<<endl;
	return 0;
}

标签:AC,洛谷,int,num,HNOI2004,maxn,include,dp
来源: https://www.cnblogs.com/yinyuqin/p/15394955.html

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

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

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

ICode9版权所有