题解:P14363 [CSP-S 2025] 谐音替换 / replace(民间数据)
FReQuenter · · 题解
sqrt 做法(
能不能过官方存疑,现在过了熨斗的
upd:洛谷过了
观察到
考虑把一种相同的 替换中的不同段 视为一组替换,那么对于
接下来的部分就是考场犯蠢。尝试把
考虑到 而且不能单开一组数据卡我这个吧再减半)相当不满,极限应该是不到 1e9 的。
球球大家都不要卡我
记得判断
::::::success[Code]
#include<bits/stdc++.h>
#define N 200005
#define S 5200005
#define P 13331
#define mod 1000000027
#define B 50
using namespace std;
struct Trie{
int trans[S][26];
int tot;
int root[N];
vector<int> ed[S];
inline void insert(int Rt,char *s,int L,int R,int id,bool o){
if(!root[Rt]) root[Rt]=++tot;
int now=root[Rt];
if(o)for(int i=L;i<=R;i++){
if(!trans[now][s[i]-'a']) trans[now][s[i]-'a']=++tot;
now=trans[now][s[i]-'a'];
}
else for(int i=R;i>=L;i--){
if(!trans[now][s[i]-'a']) trans[now][s[i]-'a']=++tot;
now=trans[now][s[i]-'a'];
}
ed[now].push_back(id);
}
inline void query(int Rt,char *s,int L,int R,vector<int> &v,bool o){
int now=root[Rt];
for(auto nx:ed[now]) v.push_back(nx);
if(o)for(int i=L;i<=R;i++){
now=trans[now][s[i]-'a'];
if(!now) break;
for(auto nx:ed[now]) v.push_back(nx);
}
else for(int i=R;i>=L;i--){
now=trans[now][s[i]-'a'];
if(!now) break;
for(auto nx:ed[now]) v.push_back(nx);
}
}
}fr,ed;
map<pair<int,int>,int> mp;
int cnt;
inline int grt(int h1,int h2){
if(mp.count({h1,h2})) return mp[{h1,h2}];
return mp[{h1,h2}]=++cnt;
}
int bs[S];
int hsh[S];
inline int geths(int L,int R){
if(L>R) return 0;
return (hsh[R]-1ll*hsh[L-1]*bs[R-L+1]%mod+mod)%mod;
}
inline int ghs(char *s,int l,int r){
int hs=0;
for(int i=l;i<=r;i++) hs=(1ll*hs*P+s[i])%mod;
return hs;
}
char s[S],t[S];
struct DS{
int col[N],val[N],now;
int &operator[](int x){
if(col[x]!=now) col[x]=now,val[x]=0;
return val[x];
}
void clear(){
now++;
}
}ds;
map<pair<int,int>,int> hscnt[N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
bs[0]=1;
for(int i=1;i<S;i++) bs[i]=1ll*bs[i-1]*P%mod;
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>(s+1)>>(t+1);
int m=strlen(s+1);
int L=0,R=m+1;
while(L+1<=m and s[L+1]==t[L+1]) L++;
while(R-1>=1 and s[R-1]==t[R-1]) R--;
if(L>=R) continue;
int h1=ghs(s,L+1,R-1),h2=ghs(t,L+1,R-1);
int id=grt(h1,h2);
if(L<=B and R>=m-B+1){
hscnt[id][{ghs(s,1,L),ghs(s,R,m)}]++;
continue;
}
fr.insert(id,s,1,L,i,0);
ed.insert(id,t,R,m,i,1);
}
while(q--){
cin>>(s+1)>>(t+1);
int m=strlen(s+1);
int L=0,R=m+1;
while(L+1<=m and s[L+1]==t[L+1]) L++;
while(R-1>=1 and s[R-1]==t[R-1]) R--;
int sum=0;
if((int)strlen(t+1)!=m){
cout<<0<<'\n';
continue;
}
int h1=ghs(s,L+1,R-1),h2=ghs(t,L+1,R-1);
if(!mp.count({h1,h2})){
cout<<0<<'\n';
continue;
}
int id=grt(h1,h2);
for(int i=1;i<=m;i++) hsh[i]=(1ll*hsh[i-1]*P+s[i])%mod;
for(int i=max(1,L-B+1);i<=L+1;i++){
for(int j=R-1;j<=min(R+B-1,m);j++){
sum+=hscnt[id][{geths(i,L),geths(R,j)}];
}
}
if(m<=B){
cout<<sum<<'\n';
continue;
}
vector<int> pre,suf;
fr.query(id,s,1,L,pre,0);
ed.query(id,t,R,m,suf,1);
ds.clear();
for(auto nx:pre) ds[nx]++;
for(auto nx:suf) sum+=ds[nx];
cout<<sum<<'\n';
}
return 0;
}
::::::