제출 #13202

#제출 시각아이디문제언어결과실행 시간메모리
13202baneling100회문 (APIO14_palindrome)C++98
100 / 100
857 ms46496 KiB
#include <stdio.h> #include <algorithm> #include <string.h> #define N_MAX 300000 using namespace std; pair <int,int> PAL[4*N_MAX]; int N, N_, MA[2*N_MAX], SA[2*N_MAX], LCP[2*N_MAX], STK[2][2*N_MAX], Top, Temp[2*N_MAX]; int Loc[2*N_MAX], Cnt, POS1[4*N_MAX], POS2[4*N_MAX], Rank[4*N_MAX], Sum[2*N_MAX], Order[2*N_MAX]; char S[2*N_MAX+1], S_[N_MAX+2]; long long Ans; 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 ]='z'+1; } 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, len, M=max(N,27), zero; for(i=1 ; i<=N ; i++) Rank[i]=S[i]-'a'+1; for(len=1 ; len<N ; len<<=1) { for(i=0 ; i<=M ; i++) Sum[i]=0; zero=0; for(i=1 ; i<=N ; i++) Sum[Rank[i+len]]++; for(i=1 ; i<=M ; i++) Sum[i]+=Sum[i-1]; for(i=1 ; i<=N ; i++) { if(Rank[i+len]) Order[++Sum[Rank[i+len]-1]]=i; else Order[++zero]=i; } for(i=0 ; i<=M ; i++) Sum[i]=0; zero=0; for(i=1 ; i<=N ; i++) Sum[Rank[Order[i]]]++; for(i=1 ; i<=M ; i++) Sum[i]+=Sum[i-1]; for(i=1 ; i<=N ; i++) { if(Rank[Order[i]]) SA[++Sum[Rank[Order[i]]-1]]=Order[i]; else SA[++zero]=Order[i]; } for(i=1 ; i<=N ; i++) { Temp[SA[i]]=Temp[SA[i-1]]; if(!(Rank[SA[i]]==Rank[SA[i-1]] && Rank[SA[i]+len]==Rank[SA[i-1]+len])) Temp[SA[i]]++; } for(i=1 ; i<=N ; i++) Rank[i]=Temp[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, p; for(i=1 ; i<=N ; i++) while(j+1<=i+MA[i]) { j++; PAL[++Cnt]=make_pair(Loc[2*i-j],2*(j-i)+1); } sort(PAL+1,PAL+Cnt+1); j=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; while(j<=Cnt && PAL[j].first==i) { p=lower_bound(STK[0]+1,STK[0]+Top+1,PAL[j].second)-STK[0]-1; POS1[j]=STK[1][p]; j++; } } Top=0; j=Cnt; for(i=N ; i>=1 ; i--) { while(STK[0][Top]>=LCP[i+1]) Top--; STK[0][++Top]=LCP[i+1]; STK[1][ Top]=i; while(j>=1 && PAL[j].first==i) { p=lower_bound(STK[0]+1,STK[0]+Top+1,PAL[j].second)-STK[0]-1; POS2[j]=STK[1][p]; j--; } } for(i=1 ; i<=Cnt ; i++) { if(S[SA[PAL[i].first]]=='z'+1) { if(Ans<(long long)(PAL[i].second/2)*(POS2[i]-POS1[i]+1)) Ans=(long long)(PAL[i].second/2)*(POS2[i]-POS1[i]+1); } else if(Ans<(long long)(PAL[i].second/2+1)*(POS2[i]-POS1[i]+1)) Ans=(long long)(PAL[i].second/2+1)*(POS2[i]-POS1[i]+1); } } 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...