WA on #92 求助
查看原帖
WA on #92 求助
502658
Ray662楼主2023/8/30 15:41

个人思路:先求两边再求中间,二分 + hash

#include <bits/stdc++.h>
#define F first
#define S second
#define mp make_pair
#define int long long
#define VI vector<int>
#define PII pair<int, int>
#define ms(a, b) memset(a, b, sizeof(a))
#define _for(i, a, b)  for (int i = (int)(a); i <= (int)(b); i ++ )
#define _all(i, a, b)  for (int i = (int)(a); i >= (int)(b); i -- )
using namespace std;
const int N = 1e5 + 5, P = 1e9 + 7;
int n, p[N], h[N][2];  // 0正向Hash, 1反向Hash 
PII res;
char s[N];
inline int Hash0(int l, int r) { return ((h[r][0] - h[l - 1][0] * p[r - l + 1]) % P + P) % P; }
inline int Hash1(int l, int r) { return ((h[l][1] - h[r + 1][1] * p[r - l + 1]) % P + P) % P; }
inline VI Manacher(char * s, int len) {
	VI res(len + 5);
	int l = 1, r = - 1, k;
	_for (i, 1, len) {
		k = (i > r ? 1 : min(res[l + r - i], r - i + 1));
		while (1 <= i - k && i + k <= len && s[i - k] == s[i + k])  k ++ ;
		res[i] = k -- ;
		if (i + k > r)  l = i - k, r = i + k;
	}
	return res;
}
inline int check(int x) {
	_for (i, 1, n)  if (i + x - 1 < n - x + 1 && Hash0(i, i + x - 1) == Hash1(n - x + 1, n))  return i;
	return 0;
}
inline void binary_search() {
	int l = 1, r = n / 2;
	while (l <= r) {
		int mid = (l + r) >> 1, cur = check(mid);
		if (cur)  res = mp(mid, cur), l = mid + 1;
		else  r = mid - 1;
	}
}
inline bool is_palin(char * s, int len) {
	_for (i, 1, (len >> 1))  if (s[i] != s[len - i + 1])  return 0;
	return 1;
}
signed main() {
	scanf("%s", s + 1), n = strlen(s + 1);
	VI v = Manacher(s, n);
	_for (i, 1, n)  if ((v[i] << 1) - 1 == n) { printf("1\n1 %lld\n", n); return 0; }
	if (is_palin(s, n)) { printf("1\n1 %lld\n", ((n & 1) ? n : n - 1)); return 0; }
	p[0] = 1;
	_for (i, 1, n)  p[i] = p[i - 1] * 27 % P, h[i][0] = (h[i - 1][0] * 27 + (s[i] - 'a' + 1)) % P;
	_all (i, n, 1)  h[i][1] = (h[i + 1][1] * 27 + (s[i] - 'a' + 1)) % P;
	binary_search();
	if (! res.F) {
		int ans1 = 0;
		_for (i, 1, n)  if (v[ans1] < v[i])  ans1 = i;
		printf("1\n%lld %lld\n", ans1 - v[ans1] + 1, (v[ans1] << 1) - 1);
		return 0;
	}
	int L = res.S + res.F, R = n - res.F, radius, ans_r = 0, mid = 0;
	_for (i, L, R) {
		if (L <= i - v[i] + 1 && i + v[i] - 1 <= R) { if (v[i] > ans_r)  mid = i, ans_r = v[i]; }
		else {
			radius = min(v[i], min(i - L + 1, R - i + 1));
			if (radius > ans_r)  mid = i, ans_r = radius;
		}
	}
	printf("3\n%lld %lld\n%lld %lld\n%lld %lld\n", res.S, res.F, mid - ans_r + 1, (ans_r << 1) - 1, n - res.F + 1, res.F);
	return 0;
}
2023/8/30 15:41
加载中...