제출 #648709

#제출 시각아이디문제언어결과실행 시간메모리
648709ymm회문 (APIO14_palindrome)C++17
100 / 100
120 ms73916 KiB
#include <bits/stdc++.h>
#define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x)
#define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x)
typedef long long ll;
typedef std::pair<int, int> pii;
typedef std::pair<ll , ll > pll;
using namespace std;

const int N = 300'010;
const int alpha = 26;
int longest_palin[N];
int second_longest[N];
string s;
int n;

struct node {
	int link = 0;
	int next[alpha] = {};
	int len = 0;
	int cnt = 0;
	bool vis = 0;
} pool[10000000];

int rt = 1;

int make_node()
{
	static int nxt = 2;
	return nxt++;
}

int lst_node = rt;
vector<int> all_nodes = {rt};
void insert_node(char c)
{
	c -= 'a';
	int new_node = make_node();
	all_nodes.push_back(new_node);
	pool[new_node].cnt = 1;
	pool[new_node].len = pool[lst_node].len + 1;
	int cur = lst_node;
	lst_node = new_node;
	while (cur) {
		if (!pool[cur].next[c]) {
			pool[cur].next[c] = new_node;
			cur = pool[cur].link;
		} else {
			break;
		}
	}
	if (!cur) {
		pool[new_node].link = rt;
		return;
	}
	int q = pool[cur].next[c];
	if (pool[cur].len + 1 == pool[q].len) {
		pool[new_node].link = q;
		return;
	}
	int clone = make_node();
	all_nodes.push_back(clone);
	pool[clone] = pool[q];
	pool[clone].cnt = 0;
	pool[clone].len = pool[cur].len + 1;
	pool[q].link = clone;
	while (cur && pool[cur].next[c] == q) {
		pool[cur].next[c] = clone;
		cur = pool[cur].link;
	}
	pool[new_node].link = clone;
}

int index2node[N];

void make_automata()
{
	Loop (i,0,n) {
		insert_node(s[i]);
		index2node[i] = lst_node;
	}
	sort(all_nodes.begin(), all_nodes.end(), [](int a, int b) {
		return pool[a].len < pool[b].len;
	});
	LoopR (i,1,all_nodes.size()) {
		int t = all_nodes[i];
		pool[pool[t].link].cnt += pool[t].cnt;
	}
}

void find_palin(int i)
{
	int j = i-1;
	while (longest_palin[j] == i || s[i-longest_palin[j]-1] != s[i]) {
		if (second_longest[j] == -1) {
			if (s[i] == s[i-1]) {
				longest_palin[i] = 2;
				second_longest[i] = j;
			} else {
				longest_palin[i] = 1;
				second_longest[i] = -1;
			}
			return;
		}
		j = second_longest[j];
	}
	longest_palin[i] = longest_palin[j]+2;
	int sec_len = -1;
	do {
		if (second_longest[j] == -1) {
			sec_len = 1 + (s[i] == s[j]);
			break;
		}
		j = second_longest[j];
	} while (longest_palin[j] == i || s[i-longest_palin[j]-1] != s[i]);
	if (sec_len == -1)
		sec_len = longest_palin[j] + 2;
	j = i - longest_palin[i] + sec_len;
	while (longest_palin[j] != sec_len)
		j = second_longest[j];
	second_longest[i] = j;
}

void find_all_palins()
{
	longest_palin[0] = 1;
	second_longest[0] = -1;
	Loop (i,1,n)
		find_palin(i);
}

int main()
{
	cin.tie(0) -> sync_with_stdio(false);
	cin >> s;
	n = s.size();
	make_automata();
	find_all_palins();
	ll ans = 0;
	Loop (i,0,n) {
		int t = index2node[i];
		while (pool[pool[t].link].len >= longest_palin[i]) {
			pool[t].vis = 1;
			t = pool[t].link;
			if (pool[t].vis)
				break;
		}
		if (pool[t].vis)
			continue;
		ans = max(ans, (ll)longest_palin[i] * pool[t].cnt);
	}
	cout << ans << '\n';
}

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

palindrome.cpp: In function 'void insert_node(char)':
palindrome.cpp:44:23: warning: array subscript has type 'char' [-Wchar-subscripts]
   44 |   if (!pool[cur].next[c]) {
      |                       ^
palindrome.cpp:45:19: warning: array subscript has type 'char' [-Wchar-subscripts]
   45 |    pool[cur].next[c] = new_node;
      |                   ^
palindrome.cpp:55:25: warning: array subscript has type 'char' [-Wchar-subscripts]
   55 |  int q = pool[cur].next[c];
      |                         ^
palindrome.cpp:66:31: warning: array subscript has type 'char' [-Wchar-subscripts]
   66 |  while (cur && pool[cur].next[c] == q) {
      |                               ^
palindrome.cpp:67:18: warning: array subscript has type 'char' [-Wchar-subscripts]
   67 |   pool[cur].next[c] = clone;
      |                  ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...