社区讨论

AC自动机 #15,16 TLE 求助

P14363[CSP-S 2025] 谐音替换参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@miedr4ql
此快照首次捕获于
2025/11/25 17:35
3 个月前
此快照最后确认于
2025/11/25 18:56
3 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=5e6+5;
int n,m,cnt,vis[N*27];
struct node{
	int id,cnt,son[27],fail;
}t[N];
int mp(char c){
	if(c=='#') return 26;
	return c-'a';
}
inline void insert(char *s,int len){
	int p=0;
	for(register int i=0;i<len;i++){
		int u=mp(s[i]);
		if(!t[p].son[u]) t[p].son[u]=++cnt;
		p=t[p].son[u];
	}
	t[p].cnt++;
}
inline void getfail(){
	queue<int>q;
	for(register int i=0;i<27;i++){
		int u=t[0].son[i];
		if(u) t[u].fail=0,q.push(u);
	}
	while(!q.empty()){
		int p=q.front();
		q.pop();
		int fa=t[p].fail;
		for(register int i=0;i<27;i++){
			int u=t[p].son[i];
			if(u){
				t[u].fail=t[fa].son[i];
				q.push(u);
			}
			else t[p].son[i]=t[fa].son[i];
		}
	}
}
inline int query(char *s,int len,int k){
	int res=0,p=0;
	for(register int i=0;i<len;i++){
		int u=mp(s[i]);
		int j=t[p].son[u];
		while(j&&vis[j]!=k){
			vis[j]=k;
			res+=t[j].cnt;
			j=t[j].fail;
		}
		p=t[p].son[u];
	}
	return res;
}
inline int merge(char *s,char *s1,char *s2){
	int len=strlen(s1);
	int c=0,c1=0,c2=0,w1=0,w2=0;
	char pre[N],sur[N];
	for(register int i=0;i<len;i++){
		if(s1[i]==s2[i]) pre[c1++]=s1[i];
		else{
			w1=i;
			break;
		}
	}
	pre[c1++]='#';
	for(register int i=len-1;i>=0;i--){
		if(s1[i]==s2[i]) sur[c2++]=s2[i];
		else{
			w2=i;
			break;
		}
	}
	sur[c2++]='#';
	for(register int i=0;i<c1;i++) s[c++]=pre[i];
	for(register int i=w1;i<=w2;i++){
		s[c++]=s1[i];
	}
	for(register int i=w1;i<=w2;i++){
		s[c++]=s2[i];
	}
	for(register int i=c2-1;i>=0;i--) s[c++]=sur[i];
	return c;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	char s1[N],s2[N],s[N<<1];
	cin>>n>>m;
	for(register int i=1;i<=n;i++){
		cin>>s1>>s2;
		int c=merge(s,s1,s2);
		if(c==strlen(s1)) continue;
		insert(s,c);
	}
	getfail();
	for(register int i=1;i<=m;i++){
		cin>>s1>>s2;
		if(strlen(s1)!=strlen(s2)){
			cout<<0<<endl;
			continue;
		}
		int c=merge(s,s1,s2);
		cout<<query(s,c,i)<<endl;
	}
	return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...