Cod sursa(job #2840828)

Utilizator loraclorac lorac lorac Data 28 ianuarie 2022 19:59:15
Problema PScPld Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("pscpld.in");
ofstream out("pscpld.out");
const int a1=29;
const int a2=31;
const int b1=666013;
const int b2=1e9+7;
const int lim=1e6+4;
/*int power(int a,int c,int b)
{
    int ans=1;
    while(c)
    {
        if(c&1) ans=(1LL*ans*a)%b;
        a=(1LL*a*a)%b;
        c>>=1;
    }
    return ans;
}*/
int st1[lim];
int st2[lim];
int dr1[lim];
int dr2[lim];
//int in1[lim];
//int in2[lim];
int p1[lim];
int p2[lim];
string s;
int n;
int main()
{
    ios_base::sync_with_stdio(false);
    in.tie(0),out.tie(0);
    in>>s;
    n=s.size();
    s='#'+s;
    //int h1=power(a1,b1-2,b1);
    //int h2=power(a2,b2-2,b2);
    //in1[0]=in2[0]=1;
    p1[0]=p2[0]=1;
    for(int i=1;i<=n;++i)
        //in1[i]=(1LL*in1[i-1]*h1)%b1,
        //in2[i]=(1LL*in2[i-1]*h2)%b2,
        p1[i]=(1LL*p1[i-1]*a1)%b1,
        p2[i]=(1LL*p2[i-1]*a2)%b2;
    for(int i=1;i<=n;++i)
    {
        st1[i]=(1LL*st1[i-1]*a1+(s[i]-'a'+1))%b1;
        st2[i]=(1LL*st2[i-1]*a2+(s[i]-'a'+1))%b2;
    }
    for(int i=n;i>=1;--i)
    {
        dr1[i]=(1LL*dr1[i+1]*a1+(s[i]-'a'+1))%b1;
        dr2[i]=(1LL*dr2[i+1]*a2+(s[i]-'a'+1))%b2;
    }
    long long ans=0;
    for(int i=1;i<=n;++i)
    {
        /// pal impar
        int l=0,r=min(i-1,n-i),med;
        while(l<r)
        {
            if(r==l+1)
                med=r;
            else med=(l+r)>>1;
            /// i-med..i and i..i+med
            int s1t=(st1[i+med]-(1LL*p1[med+1]*st1[i-1])%b1+b1)%b1;//*in1[n-i-med]
            int d1r=(dr1[i-med]-(1LL*p1[med+1]*dr1[i+1])%b1+b1)%b1;//*in1[i-med-1]
            int s2t=(1LL*st2[i+med]-(1LL*p2[med+1]*st2[i-1])%b2+b2)%b2;//*in2[n-i-med]
            int d2r=(1LL*dr2[i-med]-(1LL*p2[med+1]*dr2[i+1])%b2+b2)%b2;//*in2[i-med-1]
            if(s1t==d1r and s2t==d2r)
                l=med;
            else r=med-1;
        }
        ans+=l+1;
        //cout<<i<<" impar "<<i-l<<" : "<<i+l<<'\n';
        if(s[i]!=s[i-1])
            continue;
        /// pal par
        l=1,r=min(i-1,n-i+1),med;
        while(l<r)
        {
            if(r==l+1)
                med=r;
            else med=(l+r)>>1;
            /// i-med..i-1 and i..i+med-1
            int s1t=(st1[i+med-1]-(1LL*p1[med]*st1[i-1])%b1+b1)%b1;//*in1[n-i-med+1]
            int d1r=(dr1[i-med]-(1LL*p1[med]*dr1[i])%b1+b1)%b1;//*in1[i-med-1]
            int s2t=(1LL*st2[i+med-1]-(1LL*p2[med]*st2[i-1])%b2+b2)%b2;//*in2[n-i-med+1]
            int d2r=(1LL*dr2[i-med]-(1LL*p2[med]*dr2[i])%b2+b2)%b2;//*in2[i-med-1]
            if(s1t==d1r and s2t==d2r)
                l=med;
            else r=med-1;
        }
        ans+=l;
        //cout<<i<<" par "<<i-l<<" : "<<i+l-1<<'\n';
    }
    out<<ans<<'\n';
    return 0;
}