Submission #13184

#TimeUsernameProblemLanguageResultExecution timeMemory
13184baneling100Palindromes (APIO14_palindrome)C++98
0 / 100
11 ms53656 KiB
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#define N_MAX 300000

using namespace std;

vector <int> PAL[2*N_MAX];
vector <int> PAL2[2*N_MAX+1];
int N, N_, MA[2*N_MAX], SA[2*N_MAX], LCP[2*N_MAX+1], STK[2][2*N_MAX], Top;
int Rank[4*N_MAX], Rtemp[4*N_MAX], Len, Loc[2*N_MAX];
long long Ans;
char S[2*N_MAX+1], S_[N_MAX+2];
bool comp1(int p, int q) {return S[p]<S[q];};
bool comp2(int p, int q) {return Rank[p]<Rank[q] || (Rank[p]==Rank[q] && Rank[p+Len]<Rank[q+Len]);};

void input(void) {

    int i;

    scanf("%s",&S_[1]);
    N_=strlen(&S_[1]);
    for(i=1 ; i<=N_ ; i++) {
        S[2*i-1]=S_[i];
        S[2*i  ]='#';
    }
    S[2*N_]=NULL;
    N=2*N_-1;
}

void manacher(void) {

    int i, j=0;

    for(i=1 ; i<=N ; i++) {
        i<=j+MA[j] ? MA[i]=min(j+MA[j]-i,MA[2*j-i]) : MA[i]=0;
        while(i+MA[i]+1<=N && S[i-MA[i]-1]==S[i+MA[i]+1]) MA[i]++;
        if(j+MA[j]<i+MA[i])
            j=i;
    }
}

void suffixArray(void) {

    int i;

    for(i=1 ; i<=N ; i++)
        SA[i]=i;
    sort(SA+1,SA+N+1,comp1);
    for(i=1 ; i<=N ; i++) {
        if(S[SA[i]]==S[SA[i-1]])
            Rank[SA[i]]=Rank[SA[i-1]];
        else
            Rank[SA[i]]=i;
    }
    for(Len=1 ; Len<N ; Len<<=1) {
        sort(SA+1,SA+N+1,comp2);
        for(i=1 ; i<=N ; i++) {
            if(Rank[SA[i]]>Rank[SA[i-1]] || (Rank[SA[i]]==Rank[SA[i-1]] && Rank[SA[i]+Len]>Rank[SA[i-1]+Len]))
                Rtemp[SA[i]]=i;
            else
                Rtemp[SA[i]]=Rtemp[SA[i-1]];
        }
        for(i=1 ; i<=N ; i++)
            Rank[i]=Rtemp[i];
    }
}

void longestCommonPrefix(void) {

    int i;

    for(i=1 ; i<=N ; i++)
        Loc[SA[i]]=i;
    for(i=1 ; i<=N ; i++) {
        if(LCP[Loc[i-1]])
            LCP[Loc[i]]=LCP[Loc[i-1]]-1;
        while(S[i+LCP[Loc[i]]]==S[SA[Loc[i]-1]+LCP[Loc[i]]]) LCP[Loc[i]]++;
    }
}

void calculate(void) {

    int i, j=0, k, p;

    for(i=1 ; i<=N ; i++)
        while(j+1<=i+MA[i]) {
            j++;
            PAL[Loc[2*i-j]].push_back(2*(j-i)+1);
        }
    STK[0][Top]=-1;
    for(i=1 ; i<=N ; i++) {
        while(STK[0][Top]>=LCP[i]) Top--;
        STK[0][++Top]=LCP[i];
        STK[1][  Top]=i;
        k=PAL[i].size();
        for(j=0 ; j<k ; j++) {
            p=lower_bound(STK[0]+1,STK[0]+Top+1,PAL[i][j])-STK[0]-1;
            PAL2[STK[1][p]].push_back(PAL[i][j]);
        }
    }
    Top=0;
    for(i=1 ; i<=N+1 ; i++) {
        while(STK[0][Top]>LCP[i]) {
            if(S[SA[STK[1][Top]]]=='#') {
                if(Ans<(long long)(STK[0][Top]/2)*(i-STK[1][Top]))
                    Ans=(long long)(STK[0][Top]/2)*(i-STK[1][Top]);
            }
            else
                if(Ans<(long long)((STK[0][Top]+1)/2)*(i-STK[1][Top]))
                    Ans=(long long)((STK[0][Top]+1)/2)*(i-STK[1][Top]);
            Top--;
        }
        k=PAL2[i].size();
        for(j=0 ; j<k ; j++) {
            STK[0][++Top]=PAL2[i][j];
            STK[1][  Top]=i;
        }
    }
}

int main(void) {

    input();
    manacher();
    suffixArray();
    longestCommonPrefix();
    calculate();
    printf("%lld",Ans);

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...