제출 #486546

#제출 시각아이디문제언어결과실행 시간메모리
486546rainboyPalinilap (COI16_palinilap)C11
100 / 100
330 ms28008 KiB
#include <stdio.h>
#include <string.h>

#define N	100000
#define N_	(N * 2 + 1)
#define A	26

int min(int a, int b) { return a < b ? a : b; }
long long max(long long a, long long b) { return a > b ? a : b; }

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

char cc_[N_ + 1]; int aa0[N_], aa1[N_], sa[N_], pp[N_], st[N_ * 2], n_;

void sort(int *ii, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp;

		while (j < k)
			if (aa0[ii[j]] == aa0[i_])
				j++;
			else if (aa0[ii[j]] < aa0[i_]) {
				tmp = ii[i], ii[i] = ii[j], ii[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = ii[j], ii[j] = ii[k], ii[k] = tmp;
			}
		sort(ii, l, i);
		l = k;
	}
}

void compress() {
	int i, a;

	for (i = 0, a = 0; i < n_; i++)
		aa0[sa[i]] = i + 1 == n_ || aa0[sa[i + 1]] != aa0[sa[i]] || aa1[sa[i + 1]] != aa1[sa[i]] ? a++ : a;
}

void extend(int m) {
	int i;

	for (i = 0; i < n_; i++)
		aa1[i] = i + m < n_ ? aa0[i + m] : -1;
}

void sort_(int *aa, int *ii, int *jj) {
	static int kk[N_ + 2];
	int i, j, a;

	memset(kk, 0, (n_ + 2) * sizeof *kk);
	for (i = 0; i < n_; i++) {
		a = aa[i] + 1;
		kk[a + 1]++;
	}
	for (a = 1; a <= n_ + 1; a++)
		kk[a] += kk[a - 1];
	for (i = 0; i < n_; i++) {
		j = ii[i], a = aa[j] + 1;
		jj[kk[a]++] = j;
	}
}

void build() {
	int m, i, j, a, p;

	for (i = 0; i < n_; i++) {
		sa[i] = i;
		aa0[i] = cc_[i];
	}
	sort(sa, 0, n_);
	compress();
	for (m = 1; m < n_; m <<= 1) {
		extend(m);
		sort_(aa1, sa, pp);
		sort_(aa0, pp, sa);
		compress();
	}
	for (i = 0, p = 0; i < n_; i++, p--) {
		a = aa0[i];
		if (a + 1 < n_) {
			j = sa[a + 1], p = max(p, 0);
			while (i + p < n_ && cc_[i + p] == cc_[j + p])
				p++;
			pp[a] = p;
		}
	}
	for (a = 0; a < n_; a++)
		st[n_ + a] = pp[a];
	for (i = n_ - 1; i > 0; i--)
		st[i] = min(st[i << 1 | 0], st[i << 1 | 1]);
}

int lcp(int i, int j) {
	int l, r, tmp, p;

	if (i < 0 || i >= n_ || j < 0 || j >= n_)
		return 0;
	l = aa0[i], r = aa0[j];
	if (l > r)
		tmp = l, l = r, r = tmp;
	if (l == r)
		return n_ - sa[l];
	r--;
	p = n_;
	for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1)
			p = min(p, st[l++]);
		if ((r & 1) == 0)
			p = min(p, st[r--]);
	}
	return p;
}

int main() {
	static long long kk[N][A], ll[N + 2], mm[N + 2];
	static char cc[N + 1];
	int n, h, i, i_, j_, ij, a;
	long long k_;

	scanf("%s", cc), n = strlen(cc), n_ = n * 2 + 1;
	for (i = 0; i < n; i++)
		cc_[i] = cc_[n + n - i] = cc[i];
	cc_[n] = ' ';
	build();
	for (ij = 0; ij <= n - 1 + n - 1; ij++) {
		int p;

		h = ij / 2, p = lcp(n + n - h, ij - h), i_ = h - p, j_ = ij - i_;
		if (ij % 2 == 0) {
			ll[h] += h - i_, ll[h + 1] -= (h - i_) * 2, ll[h + 2] += h - i_;
			mm[h] -= h - i_, mm[h + 1] += (h - i_) * 2, mm[h + 2] -= h - i_;
		}
		ll[0] += h - i_, ll[1] -= h - i_;
		ll[i_ + 1]--, ll[h + 1]++, ll[ij - h + 1]++, ll[j_ + 1]--;
		mm[i_ + 1]++, mm[h + 1]--, mm[ij - h + 1]--, mm[j_ + 1]++;
		if (i_ < 0 || j_ >= n)
			continue;
		p = lcp(n + n - i_ + 1, j_ + 1) + 1;
		kk[i_][cc[j_] - 'a'] += p, kk[j_][cc[i_] - 'a'] += p;
	}
	for (i = 1; i < n; i++)
		ll[i] += ll[i - 1];
	for (i = 1; i < n; i++)
		ll[i] += ll[i - 1];
	for (i = 1; i < n; i++)
		mm[i] += mm[i - 1];
	for (i = 1; i < n; i++)
		mm[i] += mm[i - 1];
	k_ = 0;
	for (i = 0; i < n; i++)
		for (a = 0; a < A; a++)
			k_ = max(k_, kk[i][a] + ll[i] + (cc[i] == a + 'a' ? mm[i] : 0));
	printf("%lld\n", k_);
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

palinilap.c: In function 'main':
palinilap.c:126:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  126 |  scanf("%s", cc), n = strlen(cc), n_ = n * 2 + 1;
      |  ^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...