【hdu3294】Girls' research

虽然这是个manacher模板题,可是这毕竟是我第一次打manacher2333333

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char a,b[400040];
int k,lenb,ta1,ta2,mx1,mx2,hui[400040];
void manacher()
{
    for(int i=lenb;i>=0;i--)//先插入字符,可以有效处理aa一类的回文串 
        b[i+i+2]=b[i],b[i+i+1]='#';
    b[0]='*';
    mx1=0,mx2=-1;//mx1是记录的右端点最大的回文串,mx2是记录的最长回文串 
    for(int i=1;i<lenb+lenb+2;i++)
    {
        if(mx1>1)//如果说已经有一个回文串的右端点要比这个点靠右 
            hui[i]=min(hui[ta1*2-i],mx1-i);//那么说以这个点作为对称轴扩展的回文串至少是它到右端点的长度和在这个最右回文串上相对应点的答案的最小值 
        if(hui[i]==0)
            hui[i]=1;
        while(b[i+hui[i]]==b[i-hui[i]])//扩展 
            hui[i]++;//hui数组记录的是向左/右最多能扩展多少 
        if(i+hui[i]>mx1)//如果这个新的回文串能代替之前那个最右回文串 
            mx1=i+hui[i],ta1=i;//就用这个更新 
        if(hui[i]-1>mx2)//如果它现在是最长的 
            mx2=hui[i]-1,ta2=i;//用它来更新答案 
    }
}
int main()
{
    while(~scanf("%c%s",&a,b))
    {
        getchar();
        k=a-'a';lenb=strlen(b);//进行转换 
        for(int i=0;i<lenb;i++)
        {
            b[i]-=k;
            if(b[i]<'a')
                b[i]+='z'-'a'+1;
        }
        manacher();
        if(mx2==1)
            printf("No solution!\n");
        else
        {
            printf("%d %d\n",(ta2-mx2+1)/2-1,(ta2+mx2-1)/2-1);//左右端点 
            for(int i=(ta2-mx2+1);i<=(ta2+mx2-1);i++)
                if(b[i]!='#'&&b[i]!='*')
                    printf("%c",b[i]);
            printf("\n");
        }
    }
}

 

posted @ 2017-10-22 19:41  那一抹落日的橙  阅读(109)  评论(0编辑  收藏  举报