社区讨论

ACAM求条,样例过不了,玄关

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

讨论操作

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

当前回复
8 条
当前快照
1 份
快照标识符
@mhz48b8o
此快照首次捕获于
2025/11/15 01:12
3 个月前
此快照最后确认于
2025/11/16 13:46
3 个月前
查看原帖
思路参考的这篇题解
已经调了两天了,救救这个蒟蒻吧。
CPP
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define open_f_same freopen("data.in", "r", stdin);freopen("data.out", "w", stdout);
#define close_f fclose(stdin);fclose(stdout);
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define il inline
#define re register
#define PII pair<int,int>
using namespace std;
il int read();
il void write(int x);
il int gcd(int a,int b);
il int lcm(int a,int b);
il ll Pow(ll a,ll n,ll mod);
il int euler_sieve(int n);
/*
gcd(a,b)
lcm(a,b)
Pow(a,n,1) or Pow(a,n,mod)
euler_sieve(n)
*/
/*--------------------------------*/
int n,m;
struct mushichuan{
	string s1,s2,s3;
}s[(int)2e5+5];
struct wenbenchuan{
	string t1,t2,t3;
}t[(int)2e5+5];
//最长公共前后缀 
//-------------------------------------------------
void find_s(string a,string b,string& c){
	string A="",B="",C="";
	int len=a.size(),l1=0,l2=0;
	for(int i=0;i<len;i++){if(a[i]==b[i]){A+=a[i];l1++;}else break;}
	for(int i=len-1;i>=0;i--){if(a[i]==b[i]){B+=a[i];l2++;}else break;}
	C+=A+'?';
	for(int i=l1;i<len-l2;i++) C+=a[i];
	for(int i=l1;i<len-l2;i++) C+=b[i];
	C+='?';
	if(l2!=0) for(int i=l2-1;i>=0;i--) C+=B[i];
	c=C;
	return ;
}
//-------------------------------------------------
//AC自动机
//-------------------------------------------------
class Aho_Corasick_automaton{
	public:
		int son[27];
		int fail;
		int end;
}AC[(int)5e6+5];
int cnt=0;
void Build_tire_tree(string a) {
    int len=a.size();
    int now=0;
    for(int i=0;i<len;i++) {
        int index;
        if(a[i]=='?') index=26;
		else index=a[i]-'a';
        if(AC[now].son[index]==0) AC[now].son[index]=++cnt;
        now=AC[now].son[index];
    }
    AC[now].end++;
    return;
}
void Find_fail(){
	queue<int>q;
	for(int i=0;i<27&&AC[0].son[i]!=0;i++){
		AC[AC[0].son[i]].fail=0;
		q.push(AC[0].son[i]);
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=0;i<27;i++){
			if(AC[u].son[i]!=0){
				AC[AC[u].son[i]].fail=AC[AC[u].fail].son[i];
				q.push(AC[u].son[i]);
			}
			else{
				AC[u].son[i]=AC[AC[u].fail].son[i];
			}
		}
	}
	return ;
}
int Aho_Corasick_Automaton(string a){
	vector<bool>vis(cnt+1,false);
    int l=a.size();
    int now=0,ans=0;
    for(int i=0;i<l;++i){
        int index;
        if(a[i]=='?') index=26;
		else index=a[i]-'a';
        now=AC[now].son[index];
        for(int t=now;t&&!vis[t];t=AC[t].fail){
            ans+=AC[t].end;
            vis[t]=!vis[t];
        } 
    }
    return ans;
}
int main() {
	//open_f_same
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		cin>>s[i].s1>>s[i].s2;
		find_s(s[i].s1,s[i].s2,s[i].s3);
		//cout<<s[i].s3<<' '<<s[i].s3.size()<<endl;
		Build_tire_tree(s[i].s3);
	}
	AC[0].fail=0;
	Find_fail();
	for(int i=1;i<=m;i++){
		cin>>t[i].t1>>t[i].t2;
		find_s(t[i].t1,t[i].t2,t[i].t3);
		//cout<<t[i].t3<<' '<<t[i].t3.size()<<endl;
		int ans=Aho_Corasick_Automaton(t[i].t3);
		cout<<ans<<endl;
	}
	//close_f
	return 0;
}
/*--------------------------------*/
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
inline int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}
inline int lcm(int a, int b) {
	return a / gcd(a, b) * b;
}
inline ll Pow(ll a, ll n, ll mod) {
	ll ans = 1;
	a %= mod;
	while (n) {
		if (n & 1) {
			ans = (ans * a) % mod;
		}
		a = (a * a) % mod;
		n >>= 1;
	}
	return ans;
}
inline int euler_sieve(int n) {
	int cnt = 0;
	const int N = n + 5;
	int prime[N];
	bool vis[N];
	memset(vis, 0, sizeof(vis));
	memset(prime, 0, sizeof(prime));
	for (int i = 2; i <= n; i++) {
		if (!vis[i]) prime[cnt++] = i;
		for (int j = 0; j < cnt; j++) {
			if (i * prime[j] > n) {
				break;
			}
			vis[i * prime[j]] = 1;
			if (i % prime[j] == 0) {
				break;
			}
		}
	}
	return cnt;
}

回复

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

正在加载回复...