社区讨论

求条

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@mlkbetwu
此快照首次捕获于
2026/02/13 11:15
6 天前
此快照最后确认于
2026/02/13 16:24
6 天前
查看原帖
没加拓扑 TLE 55 pts,加了拓扑 WA+TLE+MLE 0 pts,玄学。
没加拓扑的CPP
#include<bits/stdc++.h>
#define int int_fast64_t
using namespace std;
int n,ch[int(5e6+5)][26],id,fail[int(5e6+5)],du[int(5e6+5)],len[int(5e6+5)];
map<int,map<string,int> > cnt;
void ins(const string& s,const string& str){
	int p=0;
	for(char c:s){
		int q=c-'a';
		if(!ch[p][q])ch[p][q]=++id;
		p=ch[p][q];
	}
	cnt[p][str]++;
	len[p]=s.length();
}
void build(){
	queue<int> q;
	for(int i=0;i<26;i++){
		if(ch[0][i]){
			q.push(ch[0][i]);
		}
	}
	while(q.size()){
		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];
				du[ch[fail[u]][i]]++;
				q.push(ch[u][i]);
			}else{
				ch[u][i]=ch[fail[u]][i];
			}
		}
	}
}
void topu(){
	queue<int> q;
	for(int i=1;i<=id;i++){
		if(du[i]==0)q.push(i);
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		if(!fail[u])continue;
		for(auto it:cnt[u])cnt[fail[u]][it.first]+=it.second;
		du[fail[u]]--;
		if(!du[fail[u]])q.push(fail[u]);
	}
}
vector<tuple<int,int,string,int> > da;
void query(const string& s){
	da.clear();
	int p=0;
	for(int i=0;i<s.length();i++){
		int q=s[i]-'a';
		while(p&&!ch[p][q])p=fail[p];
		p=ch[p][q];
		if(cnt.count(p)){
			for(auto it:cnt[p]){
				da.push_back({i-len[p]+1,len[p],it.first,it.second});
			}
		}
	}
}
int ans(const string& s1,const string& s2){
	if(s1.length()!=s2.length())return 0;
	int daan=0;
	for(auto& [ks,cd,s,js]:da){
		if(ks<0||ks+cd>s1.length())continue;
		for(int i=0;i<ks;i++)if(s1[i]!=s2[i])goto iakioi;
		for(int i=ks+cd;i<s1.length();i++)if(s1[i]!=s2[i])goto iakioi;
		for(int i=0;i<cd;i++)if(s[i]!=s2[ks+i])goto iakioi;
		daan+=js;
		iakioi:
		continue;
	}
	return daan;
}
int32_t main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		string s1,s2;
		cin>>s1>>s2;
		ins(s1,s2);
	}
	build();
	topu();
	while(q--){
		string s1,s2;
		cin>>s1>>s2;
		query(s1);
		cout<<ans(s1,s2)<<'\n';
	}
	return 0;
}
加了拓扑的CPP
#include<bits/stdc++.h>
#define int int_fast64_t
using namespace std;
int n,ch[int(5e6+5)][26],id,fail[int(5e6+5)],du[int(5e6+5)],len[int(5e6+5)];
map<int,map<string,int> > cnt;
void ins(const string& s,const string& str){
	int p=0;
	for(char c:s){
		int q=c-'a';
		if(!ch[p][q])ch[p][q]=++id;
		p=ch[p][q];
	}
	cnt[p][str]++;
	len[p]=s.length();
}
void build(){
	queue<int> q;
	for(int i=0;i<26;i++){
		if(ch[0][i]){
			q.push(ch[0][i]);
		}
	}
	while(q.size()){
		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];
				du[ch[fail[u]][i]]++;
				q.push(ch[u][i]);
			}else{
				ch[u][i]=ch[fail[u]][i];
			}
		}
	}
}
void topu(){
	queue<int> q;
	for(int i=1;i<=id;i++){
		if(du[i]==0)q.push(i);
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		if(!fail[u])continue;
		for(auto it:cnt[u])cnt[fail[u]][it.first]+=it.second;
		du[fail[u]]--;
		if(!du[fail[u]])q.push(fail[u]);
	}
}
vector<tuple<int,int,string,int> > da;
void query(const string& s){
	da.clear();
	int p=0;
	for(int i=0;i<s.length();i++){
		int q=s[i]-'a';
		while(p&&!ch[p][q])p=fail[p];
		p=ch[p][q];
		if(cnt.count(p)){
			for(auto it:cnt[p]){
				da.push_back({i-len[p]+1,len[p],it.first,it.second});
			}
		}
	}
}
int ans(const string& s1,const string& s2){
	if(s1.length()!=s2.length())return 0;
	int daan=0;
	for(auto& [ks,cd,s,js]:da){
		if(ks<0||ks+cd>s1.length())continue;
		for(int i=0;i<ks;i++)if(s1[i]!=s2[i])goto iakioi;
		for(int i=ks+cd;i<s1.length();i++)if(s1[i]!=s2[i])goto iakioi;
		for(int i=0;i<cd;i++)if(s[i]!=s2[ks+i])goto iakioi;
		daan+=js;
		iakioi:
		continue;
	}
	return daan;
}
int32_t main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		string s1,s2;
		cin>>s1>>s2;
		ins(s1,s2);
	}
	build();
	topu();
	while(q--){
		string s1,s2;
		cin>>s1>>s2;
		query(s1);
		cout<<ans(s1,s2)<<'\n';
	}
	return 0;
}

回复

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

正在加载回复...