求助洛谷 AC,POJ WA
查看原帖
求助洛谷 AC,POJ WA
214437
IntrepidStrayer楼主2021/1/1 14:17

POJ 上 n<=20000,我用的是后缀数组

#include <cstdio>
#include <algorithm>

using std :: getchar;
using std :: fread;

typedef long long ll;
inline int max(int x, int y) {return x > y ? x : y;}
inline int min(int x, int y) {return x < y ? x : y;}
inline void swap(int &x, int &y) {x ^= y ^= x ^= y;}
#define rei register int
#define rep(i, l, r) for(rei i = l, i##end = r; i <= i##end; ++i)
#define per(i, r, l) for(rei i = r, i##end = l; i >= i##end; --i)
char inputbuf[1 << 23], *p1 = inputbuf, *p2 = inputbuf;
#define getchar() (p1 == p2 && (p2 = (p1 = inputbuf) + fread(inputbuf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
	int res = 0; char ch = getchar(); bool f = true;
	for(; ch < '0' || ch > '9'; ch = getchar())
		if(ch == '-') f = false;
	for(; ch >= '0' && ch <= '9'; ch = getchar())
		res = res * 10 + (ch ^ 48);
	return f ? res : -res;
}
const int N = 20025;
int a[N], b[N], sa[N], he[N], t[N], rnk[N * 2], n, m;

inline void clear(const int nn) {
	rep(i, 0, nn) b[i] = 0;
}

void input() {
	n --;
	rep(i, 0, n) a[i] = read();
	per(i, n, 1) rnk[i] = a[i] = a[i] - a[i - 1] + 88;
	m = 180;
}

void SA() {
	for(rei len = 1; len <= n; len <<= 1) {
		clear(m);
		rep(i, 1, n) b[rnk[i + len]] ++;
		rep(i, 1, m) b[i] += b[i - 1];
		per(i, n, 1) sa[b[rnk[i + len]] --] = i;
		clear(m);
		rep(i, 1, n) b[rnk[sa[i]]] ++;
		rep(i, 1, m) b[i] += b[i - 1];
		per(i, n, 1) t[b[rnk[sa[i]]] --] = sa[i];
		rep(i, 1, n) sa[i] = t[i];
		m = 0;
		rep(i, 1, n) t[sa[i]] = rnk[sa[i]] == rnk[sa[i - 1]] && rnk[sa[i] + len] == rnk[sa[i - 1] + len] ? m : (++ m);
		rep(i, 1, n) rnk[i] = t[i];
		if(m == n) break;
	}
}

void height() {
	int now = 0, j;
	rep(i, 1, n) {
		if(rnk[i] == 1) { now = 0; continue; }
		if(now) -- now;
		j = sa[rnk[i] - 1];
		while(i + now <= n && j + now <= n && a[i + now] == a[j + now]) now ++;
		he[rnk[i]] = now;
	}
}

bool check(int len) {
	int l, r;
	l = r = sa[1];
	rep(i, 2, n) {
		if(he[i] >= len) {
			l = min(l, sa[i]);
			r = max(r, sa[i]);
			if(r - l > len) return true;
		} else l = r = sa[i];
	}
	return false;
}

int solve() {
	if(n < 9 || !check(4)) return 0;
	int l = 4, r = n, ans = -1, mid;
	while(l < r) {
		mid = (l + r) / 2;
		if(check(mid)) ans = mid, l = mid + 1;
		else r = mid;
	}
	return ans + 1;
}

signed main() {
	while(n = read()) {
		input();
		SA();
		height();
		printf("%d\n", solve());
	}
	return 0;
}
2021/1/1 14:17
加载中...