Contar (KMP + Pensar)

enlace de tema

https://ac.nowcoder.com/acm/contest/27589/B

tema

número uno número

ideas

Creemos que podemos saber que para a f ( s , t ) f(s,t)f ( s ,t ) solottLa longitud de t es menor o igual quesss puede al menos coincidir con éxito, luego encontraremos que solo necesitamos procesar la cadena con la longitud más pequeña, porque otras cadenas definitivamente tendrán unaf ( s , t ) f (s, t)f ( s ,t ) es 0, porque una cadena larga no puede llamarse subcadena de una cadena corta, pero si es solo una cadena con la longitud más pequeña,nnEncuentra kmp kmp para n cadenasSi k m p coincide, también expirará. En caso de que todas las cadenas tengan la misma longitud, observamos más y encontramos que si hay un par de diferencias entre dos cadenas cualquiera con la longitud más corta, contribuirá a la multiplicación acumulativa un0 00 , de lo contrario, todas las cadenas cortas tienen elansmismo valor, solo necesitamos repetirlo una vezkmp, y para otras cadenas, generamos directamente0 00 está bien

código

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 998244353
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f

const int N = 2e6+10;

int n;

struct KMP{
    
    
	int nextt[N];
	void get_next(string &S){
    
    
		int n = S.size(),i = 0,j = -1;
		nextt[0] = -1;
		while(i < n) {
    
    
			if(j == -1 || S[i] == S[j])
				nextt[++i] = ++j;
			else 
				j = nextt[j];
		}
	}
	//S是匹配串、T是模板串
	int get_times(string &S,string &T){
    
    //在S中查找T出现了多少次
		int cnt = 0,i = 0,j = 0;
		int len1 = S.size();
		int len2 = T.size();
		while(i < len1) {
    
    
			if(j == -1 || S[i] == T[j]) 
				i++,j++;
			else 
				j = nextt[j];
			if(j == len2) 
				j = nextt[j],cnt++;
		}
		return cnt;
	}
}kmp;

string ch[N];
int lench[N];

int main()
{
    
    
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	int min_len = INF;
	for(int i = 1;i <= n; ++i) {
    
    
		cin>>ch[i];
		lench[i] = ch[i].size();
		min_len = min(lench[i],min_len);
	}
	vector<string> Vec;
	for(int i = 1;i <= n; ++i) {
    
    
		if(lench[i] == min_len) 
			Vec.push_back(ch[i]);
	}
	bool fg = true;
	int l = Vec.size();
	for(int i = 0;i < l - 1; ++i) {
    
    
		if(Vec[i] != Vec[i + 1]) {
    
    
			fg = false;
			break;
		}
	}
	if(fg) {
    
    
		kmp.get_next(Vec[0]);
		ll ans = 1LL;
		for(int i = 1;i <= n; ++i) {
    
    
			ans = ans * (ll)kmp.get_times(ch[i],Vec[0]) % mod;
		}
		for(int i = 1;i <= n; ++i) {
    
    
			if(lench[i] == min_len) cout<<ans<<endl;
			else cout<<0<<endl;
		}
	} else {
    
    
		for(int i = 1;i <= n; ++i)
			cout<<0<<endl;
	}
	
	return 0;
}

/*
2
AA
AAA

2
0
*/

Supongo que te gusta

Origin blog.csdn.net/m0_46201544/article/details/124029453
Recomendado
Clasificación