답안 #164878

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
164878 2019-11-23T20:46:25 Z godwind 회문 (APIO14_palindrome) C++14
73 / 100
416 ms 41660 KB
#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stdio.h>
#include <cstdio>
#include <math.h>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <random>
#include <iomanip>
#include <bitset>
#include <cassert>

using namespace std;

#define int long long
#define less less228
#define left left228
#define right right228

template<typename T> void uin(T &a, T b) {
    if (b < a) a = b;
}
template<typename T> void uax(T &a, T b) {
    if (b > a) a = b;
}


random_device rnd;

template<typename T> void shuffle(vector< T > &v) {
    for (int i = 1; i < (int)v.size(); ++i) {
        swap(v[rnd() % i], v[i]);
    }
    for (int i = (int)v.size() - 1; i; --i) {
        swap(v[rnd() % i], v[i]);
    }
}

const int N = 100 * 1000 + 228;
const int BASE = 141, MOD = 1e9 + 9;
const int INF = 1e9 + 228;

int mod(int x) {
    x %= MOD;
    if (x < 0) x += MOD;
    return x;
}

vector<int> get_suffmas(string s) {
    s += '$';
    int n = (int)s.size();
    vector<int> p(n), c(n), cnt(max(256LL, n));
    for (int i = 0; i < n; ++i) {
        ++cnt[(int)s[i]];
    }
    for (int i = 1; i < (int)cnt.size(); ++i) {
        cnt[i] += cnt[i - 1];
    }
    for (int i = 0; i < n; ++i) {
        p[--cnt[(int)s[i]]] = i;
    }
    c[p[0]] = 0;
    for (int i = 1; i < n; ++i) {
        c[p[i]] = c[p[i - 1]];
        if (s[p[i]] != s[p[i - 1]]) ++c[p[i]];
    }
    for (int d = 0; (1 << d) <= n; ++d) {
        vector<int> pp(n), cc(n);
        cnt.assign(n + 1, 0);
        for (int i = 0; i < n; ++i) {
            pp[i] = p[i] - (1 << d);
            if (pp[i] < 0) pp[i] += n;
            ++cnt[c[pp[i]]];
        }
        for (int i = 1; i < n; ++i) {
            cnt[i] += cnt[i - 1];
        }
        for (int i = n - 1; i + 1; --i) {
            p[--cnt[c[pp[i]]]] = pp[i];
        }
        cc[p[0]] = 0;
        for (int i = 1; i < n; ++i) {
            cc[p[i]] = cc[p[i - 1]];
            if (c[p[i]] != c[p[i - 1]] || c[(p[i] + (1 << d)) % n] != c[(p[i - 1] + (1 << d)) % n]) {
                ++cc[p[i]];
            }
        }
        c = cc;
    }
    vector<int> ans;
    for (int i : p) {
        if (i != n - 1) ans.push_back(i);
    }
    return ans;
}

vector<int> get_lcp(string s, vector<int> p) {
    int n = (int)s.size();
    vector<int> lcp(n - 1), pos(n);
    for (int i = 0; i < n; ++i) {
        pos[p[i]] = i;
    }
    int k = 0;
    for (int i = 0; i < n; ++i) {
        if (k) --k;
        if (pos[i] == n - 1) {
            k = 0;
        } else {
            int j = p[pos[i] + 1];
            while (max(i, j) + k < n && s[i + k] == s[j + k]) ++k;
            lcp[pos[i]] = k;
        }
    }
    return lcp;
}

string s;
int n;
int h[N], hr[N], base[N];
int l_even[N], l_odd[N], st_even[N][20], st_odd[N][20], lg[N];
int answer;

int gh(int l, int r) {
    return mod(h[r] - h[l - 1] * base[r - l + 1]);
}
int gr(int l, int r) {
    return mod(hr[l] - hr[r + 1] * base[r - l + 1]);
}

void pre() {
    base[0] = 1;
    for (int i = 1; i <= n; ++i) {
        base[i] = mod(base[i - 1] * BASE);
    }
    for (int i = 1; i <= n; ++i) {
        h[i] = mod(h[i - 1] * BASE + (int)s[i - 1]);
    }
    for (int i = n; i; --i) {
        hr[i] = mod(hr[i + 1] * BASE + (int)s[i - 1]);
    }
    for (int i = 1; i <= n; ++i) {
        int l = 1, r = min(i, n - i + 1) + 1;
        while (r - l > 1) {
            int mid = (l + r) >> 1;
            if (gh(i - mid + 1, i + mid - 1) == gr(i - mid + 1, i + mid - 1)) {
                l = mid;
            } else {
                r = mid;
            }
        }
        l_odd[i] = i - l + 1;
        uax(answer, l * 2 - 1);
    }
    for (int i = 1; i < n; ++i) {
        if (s[i - 1] != s[i]) l_even[i] = INF;
        else {
            int l = 1, r = min(i, n - i) + 1;
            while (r - l > 1) {
                int mid = (l + r) >> 1;
                if (gh(i - mid + 1, i + mid) == gr(i - mid + 1, i + mid)) {
                    l = mid;
                } else {
                    r = mid;
                }
            }
            l_even[i] = i - l + 1;
            uax(answer, 2 * l);
        }
    }
    lg[1] = 0;
    for (int i = 2; i <= n; ++i) {
        lg[i] = lg[i >> 1] + 1;
    }
    l_even[n] = INF;
    for (int i = 1; i <= n; ++i) {
        st_odd[i][0] = l_odd[i];
        st_even[i][0] = l_even[i];
    }
    for (int k = 1; k <= lg[n]; ++k) {
        for (int i = 1; i <= n - (1 << k); ++i) {
            st_odd[i][k] = min(st_odd[i][k - 1], st_odd[i + (1 << (k - 1))][k - 1]);
            st_even[i][k] = min(st_even[i][k - 1], st_even[i + (1 << (k - 1))][k - 1]);
        }
    }
}

int get_odd(int l, int r) {
    int k = lg[r - l + 1];
    return min(st_odd[l][k], st_odd[r - (1 << k) + 1][k]);
}
int get_even(int l, int r) {
    int k = lg[r - l + 1];
    return min(st_even[l][k], st_even[r - (1 << k) + 1][k]);
}

int findmax(int l, int r) {
    if (l == r) return 1;
    int max_len = 1;
    int stop = l + (r - l + 1 + 1) / 2 - 1;
    int low = l;
    int high = stop + 1;
    while (high - low > 1) {
        int mid = (low + high) >> 1;
        if (get_odd(mid, stop) <= l) low = mid;
        else high = mid;
    }
    if (get_odd(low, low) <= l) uax(max_len, (low - l + 1) * 2 - 1);

    stop = l + (r - l + 1) / 2 - 1;
    low = l;
    high = stop + 1;
    while (high - low > 1) {
        int mid = (low + high) >> 1;
        if (get_even(mid, stop) <= l) low = mid;
        else high = mid;
    }
    if (get_even(low, low) <= l) uax(max_len, (low - l + 1) * 2);
    return max_len;
}


signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> s;
    n = (int)s.size();
    pre();
    vector<int> p = get_suffmas(s);
    vector<int> lcp = get_lcp(s, p);
    vector<int> gol(n), gor(n);
    for (int i = 0; i < n - 1; ++i) {
        gol[i] = -1;
        gor[i] = n - 1;
    }
    vector<int> st;
    for (int i = 0; i < n - 1; ++i) {
        while (!st.empty() && lcp[st.back()] > lcp[i]) {
            gor[st.back()] = i;
            st.pop_back();
        }
        st.push_back(i);
    }
    st.clear();
    for (int i = n - 2; i >= 0; --i) {
        while (!st.empty() && lcp[st.back()] > lcp[i]) {
            gol[st.back()] = i;
            st.pop_back();
        }
        st.push_back(i);
    }
    for (int i = 0; i < n - 1; ++i) {
        if (lcp[i] == 0) continue;
        int pal = findmax(p[i] + 1, p[i] + lcp[i] - 1 + 1);
        int cnt = gor[i] - gol[i];
        uax(answer, pal * cnt);
    }
    cout << answer << '\n';
    return 0;

}
// RU_023

/*

shironury

boootgslkfjdaojfdopsjfopjso
pgjq]pogjopsjg\qrwjopg
j
pogjqwrjgp]oqwjjqw]pjljfojpjowjow4jgopja    ohbip]aeo'rogpoaj0
[bkrw
pojgqwjp\\j\;sync_with_stdiojp
ojeofmpworuc[owejgoprwig
[sdkz
pgj
p[gjes
p0ghjqsp[

jg
prsjgopjg]prwjgoprejgopjrepogjrepog]jgoprejgrgjporeqjgoperjgoprejgopeqrjgopeqrjgoprqwjgpoqjrwsopt4ng\ojsbjsoprnbfqsn\bvhqerpogjorwo
pwewh\rwh \wjiowe orw jop jgr\p jpj o jopj gr\pj p gjop j\pj\pe jp'oj [
 k
 p[eq   fj\pjfdwj\ejopjojopjopjf;'djpfsj, ipojs\p gpsdigsj gorkgjgjrogjdojgiao'fsdvopdshpdfidopcnweojccodj [cjd;ofjd[jdspmcojc"ajno[:Afvoq[w0shbprs`nm/jP{Vadmn;'fnc[Ajojsfpfjcffor 9int i= ; 1 < nfor (int i =1; for (int i =1 ; i <= n: ++i) frfor (int j = 1; j <= ml; ++'}]]]]]]]]]
5
1 5
1 2
2 3
2 4
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 376 KB Output is correct
2 Correct 2 ms 376 KB Output is correct
3 Correct 2 ms 376 KB Output is correct
4 Correct 2 ms 376 KB Output is correct
5 Correct 2 ms 380 KB Output is correct
6 Correct 2 ms 376 KB Output is correct
7 Correct 2 ms 376 KB Output is correct
8 Correct 2 ms 376 KB Output is correct
9 Correct 2 ms 376 KB Output is correct
10 Correct 2 ms 376 KB Output is correct
11 Correct 2 ms 376 KB Output is correct
12 Correct 2 ms 376 KB Output is correct
13 Correct 2 ms 376 KB Output is correct
14 Correct 2 ms 376 KB Output is correct
15 Correct 2 ms 376 KB Output is correct
16 Correct 2 ms 376 KB Output is correct
17 Correct 5 ms 380 KB Output is correct
18 Correct 2 ms 424 KB Output is correct
19 Correct 2 ms 376 KB Output is correct
20 Correct 4 ms 508 KB Output is correct
21 Correct 2 ms 504 KB Output is correct
22 Correct 2 ms 376 KB Output is correct
23 Correct 2 ms 504 KB Output is correct
24 Correct 3 ms 504 KB Output is correct
25 Correct 2 ms 376 KB Output is correct
26 Correct 2 ms 504 KB Output is correct
27 Correct 2 ms 376 KB Output is correct
28 Correct 2 ms 376 KB Output is correct
29 Correct 9 ms 376 KB Output is correct
30 Correct 2 ms 376 KB Output is correct
31 Correct 2 ms 504 KB Output is correct
32 Correct 2 ms 504 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 764 KB Output is correct
2 Correct 3 ms 760 KB Output is correct
3 Correct 3 ms 760 KB Output is correct
4 Correct 3 ms 760 KB Output is correct
5 Correct 3 ms 760 KB Output is correct
6 Correct 3 ms 760 KB Output is correct
7 Correct 3 ms 760 KB Output is correct
8 Correct 3 ms 888 KB Output is correct
9 Correct 3 ms 760 KB Output is correct
10 Correct 3 ms 772 KB Output is correct
11 Correct 3 ms 732 KB Output is correct
12 Correct 3 ms 764 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 4604 KB Output is correct
2 Correct 18 ms 4732 KB Output is correct
3 Correct 19 ms 4604 KB Output is correct
4 Correct 18 ms 4612 KB Output is correct
5 Correct 19 ms 4600 KB Output is correct
6 Correct 18 ms 4600 KB Output is correct
7 Correct 17 ms 4624 KB Output is correct
8 Correct 14 ms 4600 KB Output is correct
9 Correct 15 ms 4600 KB Output is correct
10 Correct 20 ms 4600 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 262 ms 41552 KB Output is correct
2 Correct 238 ms 41588 KB Output is correct
3 Correct 251 ms 41660 KB Output is correct
4 Correct 234 ms 41504 KB Output is correct
5 Correct 416 ms 41592 KB Output is correct
6 Correct 366 ms 41464 KB Output is correct
7 Correct 253 ms 41488 KB Output is correct
8 Correct 258 ms 41464 KB Output is correct
9 Correct 256 ms 41464 KB Output is correct
10 Correct 383 ms 41592 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 13 ms 6276 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -