Pagini recente » Cod sursa (job #2889341) | Cod sursa (job #1835116) | Cod sursa (job #2207144) | Cod sursa (job #1456413) | Cod sursa (job #2840828)
#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;
}