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;
}

 

posted @ 2017-12-04 19:20  luyouqi233  阅读(430)  评论(0编辑  收藏  举报