社区讨论

救命啊!!!!!

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

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mkmqo5hm
此快照首次捕获于
2026/01/20 23:18
2 个月前
此快照最后确认于
2026/01/24 15:11
上个月
查看原帖
我想用树状数组将pass数组加起来,要把trie映射到树状数组中,但是我的BFS序好像出问题了,求神犇救!
问题主要出在这
CPP
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 ;
}
这是全部代码
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 条回复,欢迎继续交流。

正在加载回复...