CF17E:Palisection——题解
https://vjudge.net/problem/CodeForces-17E
http://codeforces.com/problemset/problem/17/E
题目大意:给一个长度为n的字符串,求不相交的回文串对数。
————————————————————————————
#include<cstdio> #include<cstring> #include<algorithm> #define N 2000010 #define MOD 51123987 using namespace std; typedef long long ll; ll mx,id,p[2*N],f[2*N],g[2*N]; //g[i]以i为终点的回文串个数 //f[i]以i为起点的回文串个数 char s[2*N]; int main(){ int l; scanf("%d%s",&l,s+1); s[0]='@'; ll sum=0; for(int i=l;i>=1;i--)s[i*2]=s[i]; for(int i=1;i<=2*l+1;i+=2)s[i]='#'; s[2*l+2]='?'; l=2*l+1; for(int i=1;i<=l;i++){ if(mx>i)p[i]=min(p[2*id-i],mx-i); else p[i]=1; while(s[i-p[i]]==s[i+p[i]])p[i]++; if(i+p[i]>mx){ mx=i+p[i]; id=i; } sum+=(p[i]-1)>>1; if(i%2==0)sum++; sum%=MOD; } sum=sum*(sum-1)/2; for(int i=2;i<=l;i+=2){ f[i-p[i]+2]++; f[i+2]--; g[i]++; g[i+p[i]]--; } for(int i=1;i<=l;i+=2){ f[i-p[i]+2]++; f[i+1]--; g[i+1]++; g[i+p[i]]--; } for(int i=2;i<=l;i+=2){ f[i]+=f[i-2]; f[i]%=MOD; g[i]+=g[i-2]; g[i]%=MOD; } f[l+1]=0; for(int i=l-1;i>=1;i-=2){ f[i]+=f[i+2]; f[i]%=MOD; } for(int i=2;i<=l;i+=2){ sum-=g[i]*f[i+2]%MOD; sum=(sum+MOD)%MOD; } printf("%lld\n",(sum%MOD+MOD)%MOD); return 0; }