Cod sursa(job #3367949)

Utilizator TimofeiFilipTimofei Filip Emanuel TimofeiFilip Data 12 octombrie 2026 15:12:26
Problema PScPld Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.85 kb
#include<bits/stdc++.h>
using namespace std;

const int NMAX = 1e6 + 10;
const int LOGMAX = 30;

typedef pair<int, int> pii;
typedef long long int ll;

ifstream fin("pscpld.in");
ofstream fout("pscpld.out");


int suffix[NMAX + 1][LOGMAX + 1];
string s;
int n;

struct Triplet {
    int index, left, right;
};
bool cmp(const Triplet &a, const Triplet &b) {
    if (a.left != b.left)
        return a.left < b.left;
    return a.right < b.right;
}

void compute_suffix() {
    for (int i = 0; i < n; i++)
        suffix[i][0] = s[i] - 'a';

    for (int j = 1; j <= LOGMAX; j++) {
        vector<Triplet> aux;
        for (int i = 0; i + (1 << j) - 1 < n; i++) {
            aux.push_back({
                i,
                suffix[i][j - 1],
                suffix[i + (1 << (j - 1))][j - 1]
            });
        }
        sort(aux.begin(), aux.end(), cmp);

        int rank = 0;

        for (int i = 0; i < aux.size(); i++) {
            if (i > 0 && (aux[i].left != aux[i - 1].left ||
                          aux[i].right != aux[i - 1].right)) {
                rank++;
                          }
            suffix[aux[i].index][j] = rank;
        }
    }
}
string mirror(const string &a) {
    string result = "";
    for (int i = a.size() - 1; i >= 0; i--) {
        result += a[i];
    }
    return result;
}
bool query(pii a, pii b) {
    if (a.second - a.first != b.second - b.first)
        return false;

    int len = a.second - a.first + 1;
    int log_query = 31 - __builtin_clz(len);

    bool left_son =
        suffix[a.first][log_query] ==
        suffix[b.first][log_query];

    bool right_son =
        suffix[a.second - (1 << log_query) + 1][log_query] ==
        suffix[b.second - (1 << log_query) + 1][log_query];

    return left_son && right_son;
}

int main() {
    ios::sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);

    string original;
    fin >> original;

    int m = original.size();
    string reversed = original;
    reverse(reversed.begin(), reversed.end());

    s = original + reversed;
    n = s.size();

    compute_suffix();

    ll palindroame = 0;

    for (int center = 0; center < m; center++) {
        int lo = 0, hi = min(center, m - center - 1);

        while (lo < hi) {
            int mid = (lo + hi + 1) / 2;

            if (query({center - mid, center},
    {m + (m - 1 - (center + mid)), m + (m - 1 - center)}
))
                lo = mid;
            else
                hi = mid - 1;
        }

        palindroame += lo + 1;

        lo = 0;
        hi = min(center, m - center);

        while (lo < hi) {
            int mid = (lo + hi + 1) / 2;

            if (query(
    {center - mid, center},
    {m + (m - 1 - (center + mid)), m + (m - 1 - center)}
))
                lo = mid;
            else
                hi = mid - 1;
        }

        palindroame += lo;
    }

    fout << palindroame << '\n';
    return 0;
}