Submission #23271

# Submission time Handle Problem Language Result Execution time Memory
23271 2017-05-05T17:34:07 Z Nurlykhan Palindromes (APIO14_palindrome) C++14
65 / 100
529 ms 37032 KB
#include <bits/stdc++.h>

#define pii pair<int, int>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define ll long long 
#define ld long double
#define sz(v) int(v.size())
#define all(v) v.begin(), v.end()

using namespace std;

const int N = (int) 5e5 + 10;
const int M = (int) 2e6 + 10;
const ll LINF = (ll) 1e18;
const int mod1 = (int) 1e9 + 7;
const int mod2 = (int) 1e9 + 9;
const double EPS = (double) 1e-9;
string st;
ll ans;
int n;
pii h[N], h1[N];
pii p[N];

int ncol[N], col[N], suff[N], head[N], nsuff[N], pos[N];

bool cmp1(int x, int y) {
   return st[x] < st[y];
}

void suffix_array() {
   for(int i = 0; i < n; i++) suff[i] = i;
   sort(suff, suff + n, cmp1);
   int cn = 0;
   for(int i = 0; i < n; i++) {
      if(!i || st[suff[i]] != st[suff[i - 1]]) {
         col[suff[i]] = cn++;
         head[cn - 1] = i;
      }
      else col[suff[i]] = cn - 1;
   }
   for(int i = 1; i < n; i += i) {
      for(int j = 0; j < n; j++) {
         int k = suff[j] - i;
         if(k < 0) k += n;
         nsuff[head[col[k]]++] = k;
      }
      cn = 0;
      for(int j = 0; j < n; j++)
         suff[j] = nsuff[j];
      for(int j = 0; j < n; j++) {
         if(!j || col[suff[j]] != col[suff[j - 1]] || col[(suff[j] + i) % n] != col[(suff[j - 1] + i) % n])
            ncol[suff[j]] = cn++, head[cn - 1] = j;
         else ncol[suff[j]] = cn - 1;
      }
      for(int j = 0; j < n; j++) col[j] = ncol[j];
   }
   for(int j = 0; j < n; j++) {
      pos[suff[j]] = j;
   }
}

inline pii get_hash(const int &l, const int &r) {
    pii ans = {(h[r].f - (l ? h[l - 1].f : 0) + mod1), (h[r].s - (l ? h[l - 1].s : 0) + mod2)};
    if (ans.f >= mod1) ans.f -= mod1;
    if (ans.s >= mod2) ans.s -= mod2;
    ans.f = ans.f * 1ll * p[sz(st) - 1 - r].f % mod1;
    ans.s = ans.s * 1ll * p[sz(st) - 1 - r].s % mod2;
    return ans;
}

inline pii get_revhash(const int &l, const int &r) {
    pii ans = {(h1[l].f - h1[r + 1].f + mod1), (h1[l].s - h1[r + 1].s + mod2)};
    if (ans.f >= mod1) ans.f -= mod1;
    if (ans.s >= mod2) ans.s -= mod2;
    ans.f = ans.f * 1ll * p[l].f % mod1;
    ans.s = ans.s * 1ll * p[l].s % mod2;
    return ans;
}

inline int first_diff(const pii &x, const pii &y) {
    int l = 0, r = min(x.s - x.f, y.s - y.f);
    int neq = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        if (get_hash(x.f, x.f + m) == get_hash(y.f, y.f + m)) {
            l = m + 1;
        } else {
            neq = m;
            r = m - 1;
        }
    }
    return neq;
}

bool cmp(pii x, pii y) {
    return pos[x.f] < pos[y.f];
}

vector<int> get_shit1(vector<int> v) {
    vector<int> st, ret(sz(v));
    for (int i = 0; i < sz(v); i++) {
        while (!st.empty() && v[i] <= v[st.back()]) st.pop_back();
        ret[i] = st.empty() ? 0 : st.back() + 1;
        st.pb(i);
    }
    return ret;
}

vector<int> get_shit2(vector<int> v) {
    vector<int> st, ret(sz(v));
    for (int i = sz(v) - 1; i >= 0; i--) {
        while (!st.empty() && v[i] <= v[st.back()]) st.pop_back();
        ret[i] = st.empty() ? sz(v) - 1 : st.back() - 1;
        st.pb(i);
    }
    return ret;
}

void solve_odd() {
    vector<pii> v;
    for (int i = 0; i < sz(st); i++) {
        int l = 0, r = sz(st);
        int j = 0;
        while (l <= r) {
            int m = (l + r) / 2;
            if (i - m >= 0 && i + m < sz(st) && get_hash(i, i + m) == get_revhash(i - m, i)) {
                l = m + 1;
                j = m;
            } else {
                r = m - 1;
            }
        }
        v.pb(mp(i, i + j));
    }
    sort(all(v), cmp);
    //for (auto it : v) cout << it << endl; cout << "-----\n";
    vector<int> lcp(sz(v) - 1);
    for (int i = 0; i + 1 < sz(v); i++) {
        lcp[i] = first_diff(v[i], v[i + 1]);
        if (lcp[i] == -1) 
            lcp[i] = min(v[i].s - v[i].f, v[i + 1].s - v[i + 1].f) + 1;
    }
    for (int i = 0; i < sz(v); i++) {
        ans = max(ans, 2ll * (v[i].s - v[i].f + 1) - 1);
    }
    vector<int> tmp1 = get_shit1(lcp);
    vector<int> tmp2 = get_shit2(lcp);
    for (int i = 0; i < sz(lcp); i++) {
        int occurs = tmp2[i] - tmp1[i] + 2;
        ans = max(ans, occurs * 1ll * (lcp[i] * 2 - 1));
    }
}


void solve_even() {
    vector<pii> v;
    for (int i = 0; i < sz(st); i++) {
        int l = 0, r = sz(st);
        int j = -1;
        while (l <= r) {
            int m = (l + r) / 2;
            if (i - 1 - m >= 0 && i + m < sz(st) && get_hash(i, i + m) == get_revhash(i - 1 - m, i - 1)) {
                l = m + 1;
                j = m;
            } else {
                r = m - 1;
            }
        }
        if (j != -1) 
            v.pb(mp(i, i + j));
    }
    if (v.empty()) 
        return;
    sort(all(v), cmp);
    vector<int> lcp(sz(v) - 1);
    //for (auto it : v) cout << it << endl; cout << "-----\n";
    for (int i = 0; i + 1 < sz(v); i++) {
        lcp[i] = first_diff(v[i], v[i + 1]);
        if (lcp[i] == -1) 
            lcp[i] = min(v[i].s - v[i].f, v[i + 1].s - v[i + 1].f) + 1;
    }
    for (int i = 0; i < sz(v); i++) {
        ans = max(ans, 2ll * (v[i].s - v[i].f + 1));
    }
    vector<int> tmp1 = get_shit1(lcp);
    vector<int> tmp2 = get_shit2(lcp);
    for (int i = 0; i < sz(lcp); i++) {
        int occurs = tmp2[i] - tmp1[i] + 2;
        ans = max(ans, occurs * 2ll * lcp[i]);
    }
}

int main() {
    #define fn "balls"
    #ifdef witch
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #else
//        freopen(fn".in", "r", stdin);
//        freopen(fn".out", "w", stdout);
    #endif
    cin >> st;
    st = st + "#";
    n = sz(st);
    p[0] = {1, 1};
    for (int i = 1; i < n; i++) {
        p[i].f = p[i - 1].f * 37LL % mod1;
        p[i].s = p[i - 1].s * 47LL % mod2;
    }
    for (int i = 0; i < n; i++) {
        if (i) {
            h[i] = h[i - 1];
        }
        h[i].f = (h[i].f + (st[i] - 'a' + 1 + mod1) * 1LL * p[i].f) % mod1;
        h[i].s = (h[i].s + (st[i] - 'a' + 1 + mod2) * 1LL * p[i].s) % mod2;
    }
    for (int i = n - 1; i >= 0; i--) {
        h1[i].f = (h1[i + 1].f + (st[i] - 'a' + 1 + mod1) * 1ll * p[sz(st) - 1 - i].f) % mod1;
        h1[i].s = (h1[i + 1].s + (st[i] - 'a' + 1 + mod2) * 1ll * p[sz(st) - 1 - i].s) % mod2;
    }
    suffix_array();
    solve_odd();
    solve_even();
    cout << ans;
    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 25468 KB Output is correct
2 Correct 0 ms 25468 KB Output is correct
3 Correct 0 ms 25468 KB Output is correct
4 Correct 0 ms 25468 KB Output is correct
5 Correct 0 ms 25468 KB Output is correct
6 Correct 0 ms 25468 KB Output is correct
7 Correct 0 ms 25468 KB Output is correct
8 Correct 0 ms 25468 KB Output is correct
9 Correct 0 ms 25468 KB Output is correct
10 Incorrect 0 ms 25468 KB Output isn't correct
11 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 25468 KB Output is correct
2 Correct 0 ms 25468 KB Output is correct
3 Correct 0 ms 25468 KB Output is correct
4 Correct 0 ms 25468 KB Output is correct
5 Correct 0 ms 25468 KB Output is correct
6 Correct 0 ms 25468 KB Output is correct
7 Correct 0 ms 25468 KB Output is correct
8 Correct 0 ms 25468 KB Output is correct
9 Correct 0 ms 25468 KB Output is correct
10 Correct 0 ms 25468 KB Output is correct
11 Correct 0 ms 25468 KB Output is correct
12 Correct 0 ms 25468 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 6 ms 25860 KB Output is correct
2 Correct 9 ms 25884 KB Output is correct
3 Correct 9 ms 25860 KB Output is correct
4 Correct 13 ms 25860 KB Output is correct
5 Correct 6 ms 25884 KB Output is correct
6 Correct 6 ms 25884 KB Output is correct
7 Correct 9 ms 25884 KB Output is correct
8 Correct 6 ms 25880 KB Output is correct
9 Correct 6 ms 25884 KB Output is correct
10 Correct 6 ms 25884 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 99 ms 28588 KB Output is correct
2 Correct 123 ms 28332 KB Output is correct
3 Correct 126 ms 28952 KB Output is correct
4 Correct 163 ms 28588 KB Output is correct
5 Correct 113 ms 28332 KB Output is correct
6 Correct 113 ms 28332 KB Output is correct
7 Correct 123 ms 28332 KB Output is correct
8 Correct 139 ms 28332 KB Output is correct
9 Correct 139 ms 28332 KB Output is correct
10 Correct 113 ms 28332 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 366 ms 35944 KB Output is correct
2 Correct 376 ms 35176 KB Output is correct
3 Correct 429 ms 37032 KB Output is correct
4 Correct 529 ms 35496 KB Output is correct
5 Correct 383 ms 34920 KB Output is correct
6 Correct 413 ms 35432 KB Output is correct
7 Incorrect 429 ms 34920 KB Output isn't correct
8 Halted 0 ms 0 KB -