社区讨论
救命啊!!!!!
P14363[CSP-S 2025] 谐音替换参与者 1已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mkmqo5hm
- 此快照首次捕获于
- 2026/01/20 23:18 2 个月前
- 此快照最后确认于
- 2026/01/24 15:11 上个月
我想用树状数组将pass数组加起来,要把trie映射到树状数组中,但是我的BFS序好像出问题了,求神犇救!
问题主要出在这
CPPvoid make_time(int now){
dic_sub[now]=++dic_cnt;
cout << dic_sub[now] << now << '\n';
for(int i=0 ; i<27 ; i++){
if(trie[now][i]!=0){
make_time(trie[now][i]);
}
}
dic_end[now]=dic_cnt;
return ;
}
这是全部代码
CPP#include<bits/stdc++.h>
using namespace std;
const int MAXS=5000010;
const int MAXN=200010;
int n, q;
int trie[MAXS][27];
int trie_cnt;
int End[MAXN];
int pass[MAXS];
int fail[MAXS];
int box[MAXS];
int dic_sub[MAXS];
int dic_end[MAXS];
int dic_cnt;
void ac_insert(string ins,int nows);
int ac_change(char c);
void make_fail( );
void pushup( );
void ac_add(int u,int v,int now);
struct Node{
int v, la;
};Node edge[MAXS];
int head[MAXS];
string ope(string s1,string s2);
void make_time( );
int get_next(int i);
int get_sum(int i);
int query(int i);
void add(int i);
void read( );
int work(string ins);
void write(string ins);
void ac_clear( );
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
read( );
return 0;
}
int work(string s){
int ans=0;
int len=s.size();
int now=0;
for(int i=0,path ; i<len ; i++){
path=ac_change(s[i]);
now=trie[now][path];
add(dic_sub[now]);
}
for(int i=1 ; i<=n ; i++){
if(get_sum(End[i])!=0) ans++;
}
return ans;
}
void add(int i){
while(i<=dic_cnt){
pass[i]++;
i+=get_next(i);
}
return ;
}
int query(int i){
int ret=0;
while(i>0){
ret+=pass[i];
i-=get_next(i);
}
return ret;
}
int get_sum(int i){
int ret=query(dic_end[i])-query(dic_sub[i]-1);
return ret;
}
int get_next(int i){
return i & (-i);
}
void make_time(int now){
dic_sub[now]=++dic_cnt;
cout << dic_sub[now] << now << '\n';
for(int i=0 ; i<27 ; i++){
if(trie[now][i]!=0){
make_time(trie[now][i]);
}
}
dic_end[now]=dic_cnt;
return ;
}
void ac_insert(string ins,int nows){
int len=ins.size();
int now=0;
for(int i=0,path ; i<len ; i++){
path=ac_change(ins[i]);
if(trie[now][path]==0) trie[now][path]=++trie_cnt;
now=trie[now][path];
}
End[nows]=now;
return ;
}
void make_fail( ){
int l=0, r=0;
for(int i=0 ; i<27 ; i++)
if(trie[0][i]!=0) box[r++]=trie[0][i];
int now=0;
while(r>l){
now=box[l++];
for(int i=0 ; i<27 ; i++){
if(trie[now][i]==0) trie[now][i]=trie[fail[now]][i];
else fail[trie[now][i]]=trie[fail[now]][i],
box[r++]=trie[now][i];
}
}
return ;
}
void read( ){
cin >> n >> q;
string s1, s2, ins;
for(int i=1 ; i<=n ; i++){
cin >> s1 >> s2;
ins=ope(s1,s2);
ac_insert(ins,i);
}
make_fail( );
make_time(0);
for(int i=1 ; i<=trie_cnt ; i++){
ac_add(fail[i],i,i);
}
for(int i=1 ; i<=q ; i++){
cin >> s1 >> s2;
ins=ope(s1,s2);
write(ins);
ac_clear( );
}
return ;
}
void ac_add(int u,int v,int now){
edge[now].v=v;
edge[now].la=head[u];
head[u]=now;
return ;
}
int ac_change(char c){
if('a'<=c && c<='z') c=c-'a';
else c=26;
return c;
}
string ope(string s1,string s2){
string rets, tmp;
int end1, end2;
int len=s1.size();
for(int i=0 ; i<len ; i++){
if(s1[i]!=s2[i]){
end1=i; break;
}
rets+=s1[i];
}rets+='#';
for(int i=len-1; i>=0 ; i--){
if(s1[i]!=s2[i]){
end2=i;
break;
}
tmp=s1[i]+tmp;
}
rets+=s1.substr(end1,end2-end1+1);
rets+=s2.substr(end1,end2-end1+1);
rets+='#';
rets+=tmp;
return rets;
}
void write(string ins){
cout << work(ins) << '\n';
return ;
}
void ac_clear( ){
fill(pass,pass+trie_cnt+1,0);
return ;
}
有没有巨佬救救蒟蒻qwq
回复
共 2 条回复,欢迎继续交流。
正在加载回复...