Manacher模板

Manacher模板

求最长回文子串。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

#include<vector>

#include<stack>

#include<queue>

#include<set>

#include<map>

#include<string>

#include<math.h>

#include<cctype>

#define ll long long

#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))

#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)

#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))

#define PII pair<int,int>

#define fst first

#define snd second

#define MP make_pair

#define PB push_back

#define RI(x) scanf("%d",&(x))

#define RII(x,y) scanf("%d%d",&(x),&(y))

#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))

#define DRI(x) int (x);scanf("%d",&(x))

#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))

#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))

#define RS(x) scanf("%s",x)

#define RSS(x,y) scanf("%s%s",x,y)

#define DRS(x) char x[maxn];scanf("%s",x)

#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)

#define MS0(a) memset((a),0,sizeof((a)))

#define MS1(a) memset((a),-1,sizeof((a)))

#define MS(a,b) memset((a),(b),sizeof((a)))

#define ALL(v) v.begin(),v.end()

#define SZ(v) (int)(v).size()



using namespace std;



const int maxn=5000100;

const int INF=(1<<29);

const double EPS=0.0000000001;

const double Pi=acos(-1.0);



char s[maxn],t[maxn];

int p[maxn];



int Manacher(char *s)

{

    int len=strlen(s);

    REP(i,0,len) t[2*i]='#',t[2*i+1]=s[i];

    len=strlen(t);

    int id=0,R=0;

    MS0(p);

    REP(i,0,len-1){

        if(id+p[id]<i){

            int r=0;

            while(i-r>=0&&i+r<len&&t[i-r]==t[i+r]) r++;

            p[i]=r-1;

        }

        else{

            int k=i-id;

            if(id-p[id]>id-k-p[id-k]) p[i]=id-k-(id-p[id]);

            else if(id-p[id]<id-k-p[id-k]) p[i]=p[id-k];

            else{

                int r=p[id-k];

                while(i-r>=0&&i+r<len&&t[i-r]==t[i+r]) r++;

                p[i]=r-1;

            }

        }

        if(p[i]>R) R=p[i];

        if(i+p[i]>id+p[id]) id=i;

    }

    return R;

}



int main()

{

    freopen("in.txt","r",stdin);

    int casen=1;

    while(RS(s)&&strcmp(s,"END")){

        printf("Case %d: %d\n",casen++,Manacher(s));

    }

    return 0;

}
View Code

 

你可能感兴趣的:(man)