Counting (KMP + Thinking)

topic link

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

topic

Number one number

ideas

We think we can know that for a f ( s , t ) f(s,t)f(s,t ) onlyttThe length of t is less than or equal tosss can at least match successfully, then we will find that we only need to process the string with the smallest length, because other strings will definitely have anf ( s , t ) f(s,t)f(s,t ) is 0, because a long string cannot be called a substring of a short string, but if it is only a string with the smallest length,nnFind kmp kmp for n stringsIf k m p matches, it will also time out. In case all strings have the same length, we further observe and find that if there is a pair of differences between any two strings with the shortest length, it will contribute to the cumulative multiplication a0 00 , otherwise all short strings have theanssame value, we only need to loop it oncekmp, and for other strings, we directly output0 00 is fine

code

#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
*/

Guess you like

Origin blog.csdn.net/m0_46201544/article/details/124029453