This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define ep emplace_back
#define sz(a) (a).size()
#define R real()
#define I imag()
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
typedef complex<LL> cd;
const int N=300007,lgn=20;
char str[2*N];
int suffix[2*N],lcp[2*N],Rank[2*N],tRank[2*N],stRank[2*N],tsuffix[2*N],fsuffix[2*N],nxt[2*N];
int LCA[lgn][2*N],now,mk[2*N],level[2*N],top;
PII line[2*N];
struct A{
LL a,b,c;
};
A sta[2*N];
PII intersect(PII a, PII b){
PII tmp = {a.y-b.y, b.x-a.x};
if(tmp.y<0) tmp.x*=-1,tmp.y*=-1;
return tmp;
}
int push(int idx, LL m, LL c){
line[++now] = {m,c};
PII line1, line2;
int i;
if(level[idx]>1){
line1 = intersect(line[idx],line[now]), line2 = intersect(line[idx],line[LCA[0][idx]]);
if(line1.x*line2.y<line2.x*line1.y){
int tmp=idx;
for(i=19;i>=0;i--){
if(level[LCA[i][tmp]]>1){
int p=LCA[i][tmp];
int q=LCA[0][p];
line1 = intersect(line[p],line[q]), line2 = intersect(line[p],line[now]);
if(line2.x*line1.y<=line1.x*line2.y) tmp = LCA[i][tmp];
}
}
LCA[0][now]=idx;
}else{
LCA[0][now]=idx;
}
}else{
LCA[0][now]=idx;
}
for(i=1;i<=19;i++) LCA[i][now]=LCA[i-1][LCA[i-1][now]];
level[now]=level[LCA[0][now]]+1;
return now;
}
bool cmp(int a, int b){
return str[a]<str[b];
}
void suffix_array(int n){
int i,j,k,h,cnt;
memset(Rank, -1, sizeof Rank);
for(i=1;i<=n;i++) suffix[i]=i;
sort(suffix+1, suffix+1+n, cmp);
for(i=1,cnt=0;i<=n;i++){
if(str[suffix[i]]!=str[suffix[i-1]]) cnt++;
Rank[suffix[i]]=cnt;
}
for(h=1;h<n;h<<=1){
for(i=1;i<=n;i=j){
for(j=i;j<=n&&Rank[suffix[i]]==Rank[suffix[j]];j++) stRank[suffix[j]]=i;
nxt[i]=j; fsuffix[i]=i;
}
for(i=n;i>=n-h+1;i--){
tsuffix[fsuffix[stRank[i]]]=i;
fsuffix[stRank[i]]++;
}
for(i=1;i<=n;i=nxt[i]){
for(j=i;j<nxt[i];j++){
if(suffix[j]-h<=0) continue;
int p = suffix[j]-h;
tsuffix[fsuffix[stRank[p]]]=suffix[j]-h;
fsuffix[stRank[p]]++;
}
}
for(i=1;i<=n;i++) suffix[i]=tsuffix[i];
for(i=1,cnt=1;i<=n;i=j){
for(j=i;j<=n&&Rank[suffix[i]]==Rank[suffix[j]]&&Rank[suffix[i]+h]==Rank[suffix[j]+h];j++) tRank[suffix[j]]=cnt;
cnt++;
}
for(i=1;i<=n;i++) Rank[i]=tRank[i];
}
int t=0;
for(i=1;i<=n;i++){
while(Rank[i]<n && i+t<=n && str[i+t]==str[suffix[Rank[i]+1]+t]) t++;
lcp[Rank[i]] = t;
if(t) t--;
}
}
LL calc(int idx, LL V){
int i;
if(level[idx]==1) return line[idx].x*V+line[idx].y;
PII tmp = intersect(line[idx], line[LCA[0][idx]]);
if(V*tmp.y>=tmp.x) return line[idx].x*V+line[idx].y;
for(i=18;i>=0;i--){
if(level[idx]>1){
int p = LCA[i][idx];
int q = LCA[0][p];
tmp = intersect(line[p],line[q]);
if(V*tmp.y<tmp.x) idx = LCA[i][idx];
}
}
idx = LCA[0][idx];
return line[idx].x*V+line[idx].y;
}
int main(){
int n,i,j,k,len;
scanf("%s",str+1);
len = strlen(str+1);
str[len+1]='#';
for(i=1;i<=len;i++){
str[2*len+2-i]=str[i];
}
str[2*len+2]='&';
len+=len+2;
suffix_array(len);
for(i=1;i<=len;i++){
if(suffix[i]>len/2) mk[i]=2;
else mk[i]=1;
}
LL ans=0;
sta[top++]={-1<<30,0,0};
int last1=0,last2=0;
for(i=1;i<=len;i++){
int fin;
if(mk[i]==1) last1=i,fin=last2;
else last2=i,fin=last1;
int l=0,r=top-1,m;
if(fin){
while(l<r){
m = (l+r)>>1;
if(sta[m].b<fin) l=m+1;
else r=m;
}
ans = max(ans, calc(sta[l].c,i));
}
while(top && sta[top-1].a>=lcp[i]) top--;
sta[top]={lcp[i],i,push(sta[top-1].c, lcp[i], -(LL)lcp[i]*sta[top-1].b)},top++;
}
assert((ans&1)==0);
printf("%lld",ans/2);
return 0;
}
Compilation message (stderr)
palindrome.cpp: In function 'void suffix_array(int)':
palindrome.cpp:58:13: warning: unused variable 'k' [-Wunused-variable]
int i,j,k,h,cnt;
^
palindrome.cpp: In function 'int main()':
palindrome.cpp:114:9: warning: unused variable 'n' [-Wunused-variable]
int n,i,j,k,len;
^
palindrome.cpp:114:13: warning: unused variable 'j' [-Wunused-variable]
int n,i,j,k,len;
^
palindrome.cpp:114:15: warning: unused variable 'k' [-Wunused-variable]
int n,i,j,k,len;
^
palindrome.cpp:115:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%s",str+1);
~~~~~^~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |