HDU 3294 Manacher模版题

来源:互联网 发布:厦门市网络公章 编辑:程序博客网 时间:2024/06/07 04:08

点击打开链接

题意:求最长回文子串所在的区间,然后第一个字符代表a,以后的顺推,最后输出这个区间顺推后的串

思路:Manacher轻松水过,记录下最长回文串的位置和长度就行了,然后输出时自己处理一下,大水题.......

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=200010;char str[maxn],tmp[maxn<<1];int len1[maxn<<1],pos;int init(char *st){    int len=strlen(st);    tmp[0]='@';    for(int i=1;i<=2*len;i+=2){        tmp[i]='#';        tmp[i+1]=st[i/2];    }    tmp[2*len+1]='#';    tmp[2*len+2]='$';    tmp[2*len+3]=0;    return 2*len+1;}int Manacher(char *st,int len){    int p=0,ans=0,po=0;    for(int i=1;i<=len;i++){        if(p>i) len1[i]=min(p-i,len1[2*po-i]);        else len1[i]=1;        while(st[i-len1[i]]==st[i+len1[i]]) len1[i]++;        if(len1[i]+i>p){            p=len1[i]+i;            po=i;        }        if(len1[i]>ans){            ans=len1[i];            pos=i;        }    }    return ans-1;}int main(){    char ch;    while(scanf(" %c%s",&ch,str)!=-1){        init(str);        int len=init(str);        int ans=Manacher(tmp,len);        if(ans==1) printf("No solution!\n");        else{            int le,ri;            if(pos%2==0){                le=pos/2-1-ans/2;                ri=le+ans-1;            }else{                le=pos/2-ans/2;                ri=le+ans-1;            }            printf("%d %d\n",le,ri);            int t=ch-'a';            for(int i=le;i<=ri;i++){                int k=str[i]-t;                if(k>=97) printf("%c",str[i]-t);                else printf("%c",str[i]-t+26);            }            printf("\n");        }    }    return 0;}

0 0
原创粉丝点击