Cod sursa(job #3226473)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 21 aprilie 2024 15:37:21
Problema PScPld Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize ("O1")
#pragma GCC optimize ("O2")
#pragma GCC optimize ("O3")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target ("avx2")

using namespace std;
using namespace __gnu_pbds;

#define ordered_set tree <long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update>
#define lsb(x)(x & (-x))

const long long max_size = 2e6 + 20;

long long p[max_size];

void solve ()
{
    string x;
    cin >> x;
    string s = "$";
    for (long long i = 0; i < x.size(); i++)
    {
        s += x[i];
        s += '$';
    }
    long long ans = 0, poz = 0, dr = 0, n = s.size() - 1;
    for (long long i = 1; i <= n; i++)
    {
        long long y = 2 * poz - i;
        if (dr > y)
        {
            p[i] = min(dr - i, p[y]);
        }
        while (p[i] + 1 <= i && p[i] + i - 1 <= n && s[i - p[i] - 1] == s[i + p[i] + 1])
        {
            p[i]++;
        }
        if (i + p[i] > dr)
        {
            dr = i + p[i];
        }
        if (i % 2 == 1)
        {
            ans += (p[i] + 1) / 2;
            poz = i;
        }
        else
        {
            ans += p[i] / 2;
        }
    }
    cout << ans;
    cout << '\n';
}

signed main ()
{
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#else
    freopen("pscpld.in", "r", stdin);
    freopen("pscpld.out", "w", stdout);
#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    long long tt;
    //cin >> tt;
    tt = 1;
    while (tt--)
    {
        solve();
    }
    return 0;
}