HDU 5157 Harry and magic string(Manacher)

来源:互联网 发布:怀化学院教务网络 编辑:程序博客网 时间:2024/06/03 13:49
Problem Description
Harry got a string T, he wanted to know the number of T’s disjoint palindrome substring pairs. A string is considered to be palindrome if and only if it reads the same backward or forward. For two substrings of T:x=T[a1b1],y=T[a2b2](where a1 is the beginning index of x,b1 is the ending index of x. a2,b2 as the same of y), if both x and y are palindromes and b1<a2 or b2<a1 then we consider (x, y) to be a disjoint palindrome substring pair of T.
 

Input
There are several cases.
For each test case, there is a string T in the first line, which is composed by lowercase characters. The length of T is in the range of [1,100000].
 

Output
For each test case, output one number in a line, indecates the answer.
 

Sample Input
acaaaaa
 

Sample Output
315
Hint
For the first test case there are 4 palindrome substrings of T.They are:S1=T[0,0]S2=T[0,2]S3=T[1,1]S4=T[2,2]And there are 3 disjoint palindrome substring pairs.They are:(S1,S3) (S1,S4) (S3,S4).So the answer is 3.
 
题意:问你不相交回文子串对数
分析:这道题我们借助Manacher乱搞一下,枚举i算贡献,对于每一个i来说,前面的所有回文串结尾小于i
的乘以以i开始的回文串个数,就是i点对于答案的贡献
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<set>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )const int INF=0x3f3f3f3f;typedef long long LL;const int maxn=(1e5+100)*2;char str[maxn],ma[maxn];int mp[maxn],len,l;int S[maxn],E[maxn];LL P[maxn],B[maxn];int Manacher(){    l=0;    ma[l++]='$';ma[l++]='#';    for(int i=0;i<len;i++)    {        ma[l++]=str[i];        ma[l++]='#';    }    ma[l]='\0';    int mx=0,id=0,ans=0;    for(int i=0;i<l;i++)    {        mp[i]=mx>i?min(mp[2*id-i],mx-i):1;        while(ma[i+mp[i]]==ma[i-mp[i]]) mp[i]++;        if(i+mp[i]>mx)        {            mx=i+mp[i];            id=i;        }    }}int main(){    int sx,sy,ex,ey;    while(~scanf("%s",str))    {        len=strlen(str);        Manacher();        CLEAR(S,0);        CLEAR(E,0);        for(int i=1;i<=2*len+1;i++)        {            if(i&1)            {                sx=(i-mp[i]==0?0:(i-mp[i]-1)/2+1);ex=(i-1)/2;                sy=(i-1)/2-1;      ey=(i+mp[i]-1)/2-1;                S[sx]++;           E[ex]++;                S[sy+1]--;         E[ey+1]--;            }            else            {                sx=(i-mp[i]==0?0:(i-mp[i]-1)/2+1);ex=(i-1)/2;                sy=(i-1)/2-1;      ey=(i+mp[i]-1)/2-1;                S[sx]++;           E[ex+1]++;                S[sy+1]--;         E[ey+1]--;            }        }        P[0]=0;        LL sum=0,s=0;        for(int i=0;i<len;i++)        {            S[i]++;S[i+1]--;            E[i]++;E[i+1]--;        }        for(int i=0;i<len;i++)        {            sum+=S[i];            s+=E[i];            P[i]=sum;            B[i]=s;        }        LL ans=0;sum=0;        for(int i=0;i<len;i++)        {            ans+=P[i]*sum;            sum+=B[i];        }        printf("%I64d\n",ans);    }    return 0;}


0 0
原创粉丝点击