結果

問題 No.765 ukuku 2
ユーザー りあん
提出日時 2018-12-13 00:46:51
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,009 ms / 3,000 ms
コード長 4,101 bytes
コンパイル時間 2,273 ms
コンパイル使用メモリ 206,960 KB
最終ジャッジ日時 2025-01-06 19:00:41
ジャッジサーバーID
(参考情報)
judge1 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 48
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include<bits/stdc++.h>
using namespace std;
const int M = 1000000007;
class suffix_array {
// compare (rank[i], rank[i + k]) and (rank[j], rank[j + k])
static bool compare_sa(int n, const vector<int>& rank, int i, int j, int k) {
if (rank[i] != rank[j]) return rank[i] < rank[j];
int ri = i + k <= n ? rank[i + k] : -1;
int rj = j + k <= n ? rank[j + k] : -1;
return ri < rj;
}
public:
static vector<int> construct_sa(const string& s) {
int n = s.length();
vector<int> sa(n + 1), rank(n + 1);
for (int i = 0; i <= n; ++i) {
sa[i] = i;
rank[i] = i < n ? s[i] : -1;
}
for (int k = 1; k <= n; k <<= 1) {
sort(sa.begin(), sa.end(), [&n, &k, &rank](const int& a, const int& b){ return compare_sa(n, rank, a, b, k); });
vector<int> tmp(n + 1);
for (int i = 1; i <= n; ++i)
tmp[sa[i]] = tmp[sa[i - 1]] + compare_sa(n, rank, sa[i - 1], sa[i], k);
for (int i = 0; i <= n; ++i)
rank[i] = tmp[i];
}
return sa;
}
static vector<int> construct_lcp(const string& s, const vector<int>& sa) {
int n = s.length();
vector<int> rank(n + 1), lcp(n + 1);
for (int i = 0; i <= n; ++i) rank[sa[i]] = i;
int h = 0;
for (int i = 0; i < n; ++i) {
if (h > 0) --h;
for (int j = sa[rank[i] - 1]; j + h < n && i + h < n; ++h)
if (s[j + h] != s[i + h]) break;
lcp[rank[i] - 1] = h;
}
return lcp;
}
};
class segtree {
private:
int n, s, t;
vector<int> tr;
const int ex = M;
int q(int k, int l, int r) {
return r <= s || t <= l ? ex : s <= l && r <= t ? tr[k]
: min(q(k << 1 | 1, l, (l + r) >> 1), q((k + 1) << 1, (l + r) >> 1, r));
}
public:
segtree(int m) {
n = 1;
while (n < m) n <<= 1;
tr = vector<int>((n << 1) - 1, ex);
}
void update(int j, const int& x) {
int i = j + n - 1;
tr[i] = x;
while (i > 0) { i = (i - 1) >> 1; tr[i] = min(tr[i << 1 | 1], tr[(i + 1) << 1]); }
}
// [s, t)
int run(int _s, int _t) { s = _s; t = _t; return q(0, 0, n); }
};
int main() {
string s;
cin >> s;
int n = s.length();
int m = n * 2 + 1;
string rev = s;
reverse(rev.begin(), rev.end());
string ss = s + "#" + rev;
vector<int> sa = suffix_array::construct_sa(ss);
vector<int> lcp = suffix_array::construct_lcp(ss, sa);
vector<int> rank(m + 1);
segtree sg(m + 1);
for (int i = 0; i <= m; ++i) {
sg.update(i, lcp[i]);
// cout << lcp[i] << "\n";
rank[sa[i]] = i;
}
int ans = 1;
for (int i = 1; i < n; ++i) {
{
int ri = i, li = m - i;
int len = sg.run(min(rank[ri], rank[li]), max(rank[ri], rank[li]));
ri += len;
li += len;
ans = max(ans, len * 2 - 2);
if (ri <= n && li + 1 <= m) {
int len1 = sg.run(min(rank[ri], rank[li + 1]), max(rank[ri], rank[li + 1]));
ans = max(ans, len * 2 + len1 * 2);
}
if (ri + 1 <= n && li <= m) {
int len1 = sg.run(min(rank[ri + 1], rank[li]), max(rank[ri + 1], rank[li]));
ans = max(ans, len * 2 + len1 * 2);
}
}
{
int ri = i, li = m - i + 1;
int len = sg.run(min(rank[ri], rank[li]), max(rank[ri], rank[li]));
ri += len;
li += len;
ans = max(ans, len * 2);
if (ri <= n && li + 1 <= m) {
int len1 = sg.run(min(rank[ri], rank[li + 1]), max(rank[ri], rank[li + 1]));
ans = max(ans, len * 2 + len1 * 2 + 1);
}
if (ri + 1 <= n && li <= m) {
int len1 = sg.run(min(rank[ri + 1], rank[li]), max(rank[ri + 1], rank[li]));
ans = max(ans, len * 2 + len1 * 2 + 1);
}
}
}
cout << ans << "\n";
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0