[Luo Gu P2375] [NOI2014] Zoo

Subject to the effect: find a string every $ S $ of $ num [i] $, up to $ 5 $ Group Asks, $ | S | \ leqslant10 ^

$ Num [i] $ is defined as $ S_ {1, i} $ length does not exceed the number of $ \ lfloor \ dfrac i2 \ rfloor $ $ a $ border of

Solution: a similar $ KMP $. I found a string of $ border $ $ border $ string must be the original $ border $, and if each is the longest $ border $, then all of $ border $ will be enumerated to. Order $ res [i] $ denotes $ S_ {1, i} $ border of $ $ $ 1 + $ number (i.e., including $ S_ {1, i} $if the $ S_ {1, i} $ is $ S_ {1, j} $ a and $ I $ $ $ border to meet all $ i \ leqslant \ lfloor \ dfraclargest, the $ num [j] = res [$ res $ array can be obtained at the time of passing seeking $ nxt $ array. Now is to quickly find $ i $ to $ j $. Similarly $ $ by the KMP method, to obtain the corresponding $ $ I $ J $, $ j + on the $ 1, $ I $ directly to modify, if $ i> \ lfloor \ dfrac j2$ repeated $ i = nxt [i] $ until the condition. Such complexity and $ is the same as the KMP $ $ O (n) $ of

Card point: None

 

C++ Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
const int maxn = 1e6 + 10, mod = 1e9 + 7;

int Tim, n, ans;
char s[maxn];
int nxt[maxn], res[maxn];
int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	std::cin >> Tim;
	while (Tim --> 0) {
		std::cin >> s + 1;
		n = strlen(s + 1), ans = 1;
		res[1] = 1;
		for (int i = 2, j = 0; i <= n; ++i) {
			while (j && s[i] != s[j + 1]) j = nxt[j];
			nxt[i] = j += s[i] == s[j + 1], res[i] = res[j] + 1;
		}
		for (int i = 2, j = 0; i <= n; ++i) {
			while (j && s[i] != s[j + 1]) j = nxt[j];
			j += s[i] == s[j + 1];
			while (j > i / 2) j = nxt[j];
			ans = static_cast<long long> (res[j] + 1) * ans % mod;
		}
		std::cout << ans << '\n';
	}
	return 0;
}

  

Guess you like

Origin www.cnblogs.com/Memory-of-winter/p/11305425.html