Submission #109860

#TimeUsernameProblemLanguageResultExecution timeMemory
109860sealnot123Palindromes (APIO14_palindrome)C++14
0 / 100
11 ms4876 KiB
#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[N]; int suffix[N],lcp[N],Rank[N],tRank[N],stRank[N],tsuffix[N],fsuffix[N],nxt[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; } void print(int idx){ while(idx) printf("====%lld %lld\n",line[idx].x,line[idx].y),idx=LCA[0][idx]; } int push(int idx, LL m, LL c){ line[++now] = {m,c}; LCA[0][now]=idx; level[now]=level[idx]+1; int i; for(i=1;i<=18;i++) LCA[i][now] = LCA[i-1][LCA[i-1][now]]; int tmp=now; for(i=18;i>=0;i--){ if(level[LCA[i][tmp]]>1){ int p=LCA[i][tmp]; int q=LCA[0][p]; PII 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]=LCA[0][tmp]; for(i=1;i<=18;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; // printf("%d %d %d\n",i,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; // binary search! 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; } // for(i=1;i<=len;i++) printf("%d : %d %d %s\n",i,lcp[i],mk[i],str+suffix[i]); LL ans=0; sta[top++]={-1<<30,0,0}; int last1=0,last2=0; for(i=1;i<=len;i++){ int fin; // printf("print stack #%d:\n",i); // for(j=1;j<top;j++) printf("%lld %lld %lld\n",sta[j].a,sta[j].b,sta[j].c); // print(sta[top-1].c); 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; } // printf("***%d %d %d %lld\n",i,sta[l].b,l,calc(sta[l].c,i)); ans = max(ans, calc(sta[l].c,i)); } while(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:54:13: warning: unused variable 'k' [-Wunused-variable]
     int i,j,k,h,cnt;
             ^
palindrome.cpp: In function 'int main()':
palindrome.cpp:112:9: warning: unused variable 'n' [-Wunused-variable]
     int n,i,j,k,len;
         ^
palindrome.cpp:112:13: warning: unused variable 'j' [-Wunused-variable]
     int n,i,j,k,len;
             ^
palindrome.cpp:112:15: warning: unused variable 'k' [-Wunused-variable]
     int n,i,j,k,len;
               ^
palindrome.cpp:113:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%s",str+1);
     ~~~~~^~~~~~~~~~~~
#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...