社区讨论
求条
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 条回复,欢迎继续交流。
正在加载回复...