ICode9

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

CF1163D Mysterious Code

2021-06-13 11:32:49  阅读:230  来源: 互联网

标签:insert AC Code int CF1163D wgj 权值 Mysterious getchar


一道十分可做的纸糊串题
题面
首先涉及到匹配那一定用AC自动机来解决
可以想到在s串的末尾节点上打个1,t串末尾打个-1,那么把c串在上面跑匹配,最终统计的结果就是$s的出现次数-t的出现次数$
定义状态$f[i][j]$表示在c串的第i个位置,AC自动机上的第j个节点的最大结果
在AC自动机上跑,能匹配就跳,加上这个点的权值
但如果出现了如第二个的数据,那么我们这种做法似乎不对
因为权值统计的出现问题
我们如果只是像上述那样标记权值的话,那么第二个a只会被算一次,所以有些点也必须标记权值
自然是从哪个点来,就加上那个点的权值
代码

#include<bits/stdc++.h>
using namespace std;
inline int read() {
	int s=1,a=0;
	char c=getchar();
	while(!isdigit(c)) {
		if(c=='-') s=-s;
		c=getchar();
	}
	while(isdigit(c)) {
		a=a*10+c-'0';
		c=getchar();
	}
	return s*a;
}
const int N=4e3+8;
int n;
#define inf 0x7f7f7f7f
struct AC {
	int son[N][28],fail[N],cnt,w[N],bfn[N],lenth;
	void insert(int l,string s,int opt) {
		int p=0;
		for(int i=0;i<l;i++) {
			char c=s[i]-'a'+1;
			if(!son[p][c]) son[p][c]=++cnt;
			p=son[p][c];
		}
		w[p]+=1*opt;
	}
	void bfs() {
		queue <int> q;
		bfn[++lenth]=0;
		for(int i=1;i<=26;i++) {
			if(son[0][i]) q.push(son[0][i]),bfn[++lenth]=son[0][i];
		}
		while(q.size()) {
			int p=q.front();
			bfn[++lenth]=p;
			q.pop();
			for(int i=1;i<=26;i++) {
				if(son[p][i]) {
					fail[son[p][i]]=son[fail[p]][i];
					q.push(son[p][i]);
				}
				else son[p][i]=son[fail[p]][i];
			}
		}
		for(int i=1;i<=lenth;i++) {
			w[bfn[i]]+=w[fail[bfn[i]]];
		}
	}
} wgj;
int f[N][N];
string s,t;
char c[2000];
int main() {
	scanf("%s",(c+1));n=strlen(c+1);
	cin>>s;wgj.insert(s.size(),s,1);
	cin>>t;wgj.insert(t.size(),t,-1);
	wgj.bfs();
	for(int i=0;i<=n;i++) {
		for(int j=0;j<=wgj.cnt;j++) {
			f[i][j]=-inf/3;
		}
	}
	f[0][0]=0;
	for(int i=0;i<n;i++) {
		for(int j=0;j<=wgj.cnt;j++) {
			if(f[i][j]==-inf/3) continue;
			for(int ch=1;ch<=26;ch++) {
				int to=wgj.son[j][ch];
				if(c[i+1]==ch+'a'-1||c[i+1]=='*')
					f[i+1][to]=max(f[i+1][to],f[i][j]+wgj.w[to]);
			}
		}
	}
	int ans=-inf;
	for(int i=0;i<=wgj.cnt;i++) {
		ans=max(ans,f[n][i]);
	}
	cout<<ans<<endl;
	return 0;
}

有一个细节,就是c字符串的下标必须从1开始,因为你是通过$f[0][0]$去更新每一个$f[i][j]$,如果不从1开始,可能c的第一个字符的情况就更新不到

标签:insert,AC,Code,int,CF1163D,wgj,权值,Mysterious,getchar
来源: https://www.cnblogs.com/rpdg-bz/p/14879927.html

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

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

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

ICode9版权所有