이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC target("avx")
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ld long double
#define ll long long
mt19937 rnd(51);
const int INF = 1e9, MOD1 = 1e9 + 7, p1 = 31, MOD2 = 1e9 + 33, p2 = 37;
ll BIGINF = 1e18;
bool is_palindrome(string s) {
return s == (string){s.rbegin(), s.rend()};
}
ll solve1(string s) {
int n = s.size(), ans = -INF;
map<string, int> cnt;
for (int i = 0; i < n; i++) {
for (int j = 1; j + i <= n; j++) {
cnt[s.substr(i, j)]++;
}
}
for (int i = 0; i < n; i++) {
for (int j = n - i; j >= 1; j--) {
if (is_palindrome(s.substr(i, j))) {
ans = max(ans, cnt[s.substr(i, j)] * j);
}
}
}
return ans;
}
struct Hash {
ll MOD, p;
vector<ll> po, h;
Hash(string s, ll MOD_, ll p_) {
MOD = MOD_, p = p_;
int n = s.size();
po.resize(n + 1);
h.resize(n + 1);
po[0] = 1;
for (int i = 1; i <= n; i++) {
po[i] = (po[i - 1] * p) % MOD;
}
for (int i = 0; i < n; i++) {
h[i + 1] = (h[i] * p + s[i] - 'a' + 1) % MOD;
}
}
int get(int l, int r) {
r++;
return (((h[r] - h[l] * po[r - l]) % MOD) + MOD) % MOD;
}
};
struct SegTree {
vector<int> t;
SegTree(int n) {
t.resize(4 * n, -1);
}
void update(int v, int tl, int tr, int l, int r, int val) {
if (l > r) return;
if (tl == l && tr == r) {
t[v] = max(t[v], val);
return;
}
int tm = (tl + tr) / 2;
update(2 * v, tl, tm, l, min(r, tm), val), update(2 * v + 1, tm + 1, tr, max(l, tm + 1), r, val);
}
int get(int v, int l, int r, int pos) {
if (l == r) {
return t[v];
}
int m = (l + r) / 2;
if (pos <= m) {
return max(t[v], get(2 * v, l, m, pos));
} else {
return max(t[v], get(2 * v + 1, m + 1, r, pos));
}
}
};
vector<int> suffix_array(string s) {
s += '#';
int n = s.size();
vector<int> p, c(n);
vector<vector<int>> a(n);
map<char, vector<int>> all;
for (int i = 0; i < n; i++) {
all[s[i]].pb(i);
}
int now = 0;
for (auto to : all) {
for (auto t : to.second) {
c[t] = now;
p.pb(t);
}
now++;
}
int mx = now, i, k, j;
for (i = 0; mx < n; ++i) {
int val = (1 << i);
for (int j = 0; j < mx; j++) a[j].clear();
for (int j = 0; j < n; j++) {
int k = (p[j] - val + n) % n;
a[c[k]].pb(k);
}
auto _c = c;
int now = -1, ind = 0;
for (k = 0; k < mx; ++k) {
for (j = 0; j < a[k].size(); ++j) {
if (j == 0 || _c[(a[k][j] + val) % n] != _c[(a[k][j - 1] + val) % n]) now++;
c[a[k][j]] = now;
p[ind++] = a[k][j];
}
}
mx = now + 1;
}
return {p.begin() + 1, p.end()};
}
ll solve2(string s) {
int n = s.size();
ll ans = -BIGINF;
Hash h1(s, MOD1, p1), h1rev((string){s.rbegin(), s.rend()}, MOD1, p1), h2(s, MOD2, p2), h2rev((string){s.rbegin(), s.rend()}, MOD2, p2);
SegTree odd(n), even(n);
for (int i = 0; i < n; i++) {
int l = 0, r = n;
while (r - l > 1) {
int mid = (r + l) / 2;
if (i - mid >= 0 && i + mid < n && h1.get(i - mid, i + mid) == h1rev.get(n - i - mid - 1, n - i + mid - 1) && h2.get(i - mid, i + mid) == h2rev.get(n - i - mid - 1, n - i + mid - 1)) {
l = mid;
} else {
r = mid;
}
}
odd.update(1, 0, n - 1, i - l, i, i);
if (i + 1 < n && s[i] == s[i + 1]) {
int l = 0, r = n;
while (r - l > 1) {
int mid = (r + l) / 2;
if (i - mid >= 0 && i + mid + 1 < n && h1.get(i - mid, i + mid + 1) == h1rev.get(n - i - mid - 2, n - i + mid - 1) && h2.get(i - mid, i + mid + 1) == h2rev.get(n - i - mid - 2, n - i + mid - 1)) {
l = mid;
} else {
r = mid;
}
}
even.update(1, 0, n - 1, i - l, i, i);
}
}
vector<int> pos(n, -1);
for (int i = 0; i < n; i++) {
int j = odd.get(1, 0, n - 1, i), k = even.get(1, 0, n - 1, i);
if (j != -1) {
pos[i] = max(pos[i], i + 2 * (j - i));
}
if (k != -1) {
pos[i] = max(pos[i], i + 1 + 2 * (k - i));
}
}
vector<int> arr = suffix_array(s), p, cnt(n, 1);
for (int i = 0; i + 1 < n; i++) {
if (s[arr[i]] != s[arr[i + 1]]) {
p.pb(0);
} else {
int l = 0, r = n;
while (r - l > 1) {
int mid = (r + l) / 2;
if (max(arr[i], arr[i + 1]) + mid <= n && h1.get(arr[i], arr[i] + mid - 1) == h1.get(arr[i + 1], arr[i + 1] + mid - 1) && h2.get(arr[i], arr[i] + mid - 1) == h2.get(arr[i + 1], arr[i + 1] + mid - 1)) {
l = mid;
} else {
r = mid;
}
}
p.pb(l);
}
}
deque<int> q;
for (int i = n - 1; i >= 0; i--) {
if (i + 1 < n) {
while (q.size() > 0 && p[i] < p[q.back()]) {
q.pop_back();
}
q.pb(i);
}
if (pos[arr[i]] != -1) {
int len = pos[arr[i]] - arr[i] + 1;
if (i + 1 < n && p[q.back()] >= len) {
if (p[q[0]] >= len) {
cnt[i] += n - i - 1;
} else {
int l = -1, r = q.size();
while (r - l > 1) {
int mid = (r + l) / 2;
if (p[q[mid]] >= len) {
r = mid;
} else {
l = mid;
}
}
cnt[i] += q[r - 1] - i;
}
}
}
}
q.clear();
for (int i = 0; i < n; i++) {
if (pos[arr[i]] != -1) {
int len = pos[arr[i]] - arr[i] + 1;
if (i - 1 >= 0 && p[q.back()] >= len) {
if (p[q[0]] >= len) {
cnt[i] += i;
} else {
int l = -1, r = q.size();
while (r - l > 1) {
int mid = (r + l) / 2;
if (p[q[mid]] >= len) {
r = mid;
} else {
l = mid;
}
}
cnt[i] += i - q[r - 1] - 1;
}
}
ans = max(ans, (ll)cnt[i] * len);
}
while (q.size() > 0 && p[i] < p[q.back()]) {
q.pop_back();
}
if (i + 1 < n) {
q.pb(i);
}
}
return ans;
}
signed main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif // LCOAL
ios_base::sync_with_stdio(0);
cin.tie(0);
while (0) {
int n = rnd() % 15 + 1;
string s = "";
for (int i = 0; i < n; i++) {
s += rnd() % 5 + 'a';
}
auto res1 = solve1(s), res2 = solve2(s);
if (res1 != res2) {
cout << s << endl << res1 << ' ' << res2 << endl;
return 0;
}
cout << "ok" << endl;
}
string s;
cin >> s;
cout << solve2(s) << endl;
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
In file included from /usr/include/x86_64-linux-gnu/c++/10/bits/gthr.h:148,
from /usr/include/c++/10/ext/atomicity.h:35,
from /usr/include/c++/10/bits/ios_base.h:39,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/istream:38,
from /usr/include/c++/10/sstream:38,
from /usr/include/c++/10/complex:45,
from /usr/include/c++/10/ccomplex:39,
from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:54,
from palindrome.cpp:9:
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:102:1: error: attribute value 'tune=native' was already specified in 'target' attribute
102 | __gthrw(pthread_once)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:102:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:103:1: error: attribute value 'tune=native' was already specified in 'target' attribute
103 | __gthrw(pthread_getspecific)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:103:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:104:1: error: attribute value 'tune=native' was already specified in 'target' attribute
104 | __gthrw(pthread_setspecific)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:104:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:106:1: error: attribute value 'tune=native' was already specified in 'target' attribute
106 | __gthrw(pthread_create)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:106:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:107:1: error: attribute value 'tune=native' was already specified in 'target' attribute
107 | __gthrw(pthread_join)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:107:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:108:1: error: attribute value 'tune=native' was already specified in 'target' attribute
108 | __gthrw(pthread_equal)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:108:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:109:1: error: attribute value 'tune=native' was already specified in 'target' attribute
109 | __gthrw(pthread_self)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:109:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:110:1: error: attribute value 'tune=native' was already specified in 'target' attribute
110 | __gthrw(pthread_detach)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:110:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:112:1: error: attribute value 'tune=native' was already specified in 'target' attribute
112 | __gthrw(pthread_cancel)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:112:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:114:1: error: attribute value 'tune=native' was already specified in 'target' attribute
114 | __gthrw(sched_yield)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:114:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:116:1: error: attribute value 'tune=native' was already specified in 'target' attribute
116 | __gthrw(pthread_mutex_lock)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:116:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:117:1: error: attribute value 'tune=native' was already specified in 'target' attribute
117 | __gthrw(pthread_mutex_trylock)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:117:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:119:1: error: attribute value 'tune=native' was already specified in 'target' attribute
119 | __gthrw(pthread_mutex_timedlock)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:119:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:121:1: error: attribute value 'tune=native' was already specified in 'target' attribute
121 | __gthrw(pthread_mutex_unlock)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:121:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:122:1: error: attribute value 'tune=native' was already specified in 'target' attribute
122 | __gthrw(pthread_mutex_init)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:122:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:123:1: error: attribute value 'tune=native' was already specified in 'target' attribute
123 | __gthrw(pthread_mutex_destroy)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:123:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:125:1: error: attribute value 'tune=native' was already specified in 'target' attribute
125 | __gthrw(pthread_cond_init)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:125:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:126:1: error: attribute value 'tune=native' was already specified in 'target' attribute
126 | __gthrw(pthread_cond_broadcast)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:126:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:127:1: error: attribute value 'tune=native' was already specified in 'target' attribute
127 | __gthrw(pthread_cond_signal)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:127:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:128:1: error: attribute value 'tune=native' was already specified in 'target' attribute
128 | __gthrw(pthread_cond_wait)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:128:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:129:1: error: attribute value 'tune=native' was already specified in 'target' attribute
129 | __gthrw(pthread_cond_timedwait)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:129:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:130:1: error: attribute value 'tune=native' was already specified in 'target' attribute
130 | __gthrw(pthread_cond_destroy)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:130:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:132:1: error: attribute value 'tune=native' was already specified in 'target' attribute
132 | __gthrw(pthread_key_create)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:132:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:133:1: error: attribute value 'tune=native' was already specified in 'target' attribute
133 | __gthrw(pthread_key_delete)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:133:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:134:1: error: attribute value 'tune=native' was already specified in 'target' attribute
134 | __gthrw(pthread_mutexattr_init)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:134:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:135:1: error: attribute value 'tune=native' was already specified in 'target' attribute
135 | __gthrw(pthread_mutexattr_settype)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:135:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:136:1: error: attribute value 'tune=native' was already specified in 'target' attribute
136 | __gthrw(pthread_mutexattr_destroy)
| ^~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:136:1: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:237:10: error: attribute value 'tune=native' was already specified in 'target' attribute
237 | __gthrw2(__gthrw_(__pthread_key_create),
| ^~~~~~~~
/usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:237:10: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:73:3: error: attribute value 'tune=native' was already specified in 'target' attribute
73 | _GLIBCXX_GTHRW(rwlock_rdlock)
| ^~~~~~~~~~~~~~
/usr/include/c++/10/shared_mutex:73:3: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:74:3: error: attribute value 'tune=native' was already specified in 'target' attribute
74 | _GLIBCXX_GTHRW(rwlock_tryrdlock)
| ^~~~~~~~~~~~~~
/usr/include/c++/10/shared_mutex:74:3: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:75:3: error: attribute value 'tune=native' was already specified in 'target' attribute
75 | _GLIBCXX_GTHRW(rwlock_wrlock)
| ^~~~~~~~~~~~~~
/usr/include/c++/10/shared_mutex:75:3: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:76:3: error: attribute value 'tune=native' was already specified in 'target' attribute
76 | _GLIBCXX_GTHRW(rwlock_trywrlock)
| ^~~~~~~~~~~~~~
/usr/include/c++/10/shared_mutex:76:3: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:77:3: error: attribute value 'tune=native' was already specified in 'target' attribute
77 | _GLIBCXX_GTHRW(rwlock_unlock)
| ^~~~~~~~~~~~~~
/usr/include/c++/10/shared_mutex:77:3: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:91:4: error: attribute value 'tune=native' was already specified in 'target' attribute
91 | __gthrw(pthread_rwlock_timedrdlock);
| ^~~~~~~
/usr/include/c++/10/shared_mutex:91:4: error: attribute value 'tune=native' was already specified in 'target' attribute
/usr/include/c++/10/shared_mutex:101:4: error: attribute value 'tune=native' was already specified in 'target' attribute
101 | __gthrw(pthread_rwlock_timedwrlock);
| ^~~~~~~
/usr/include/c++/10/shared_mutex:101:4: error: attribute value 'tune=native' was already specified in 'target' attribute
palindrome.cpp: In function 'std::vector<int> suffix_array(std::string)':
palindrome.cpp:121:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
121 | for (j = 0; j < a[k].size(); ++j) {
| ~~^~~~~~~~~~~~~