Sam feels more intuitive to write than SA (?). )
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib > #include <algorithm> #define LL long long#define N 600005using namespace Std;inline int read () {int Ret=0;char ch= GetChar (); bool Flag=0;while (ch< ' 0 ' | | Ch> ' 9 ') {flag=ch== '-'; Ch=getchar ();} while (' 0 ' <=ch&&ch<= ' 9 ') {Ret=ret*10-48+ch;ch=getchar ();} return Flag?-ret:ret;} inline char readch () {char ch=getchar (); while (!isalpha (CH)) Ch=getchar (); return ch;} struct Sam{int max0[n],max1[n],min0[n],min1[n]; #define U q[i]struct samnode{int par,mx,go[26],rights; Samnode () {}samnode (int _mx):p ar (0), MX (_MX), rights (0) {memset (go,0,sizeof (Go));}} T[n];int last,size;int newnode (int _mx) {t[++size]=samnode (_MX); max0[size]=max1[size]=-(MIN0[SIZE]=MIN1[SIZE]=2E9) ; return size;} void Clear () {size=0;last=newnode (0);} void Extend (char c,int data) {c-= ' a '; int p=last,np=newnode (t[p].mx+1); T[np].rights=1;max0[np]=min0[np]=data;for (;p &&!T[P].GO[C];p =t[p].par) t[p].go[c]=np;if(!p) T[np].par=1;else{int q=t[p].go[c];if (t[p].mx+1==t[q].mx) t[np].par=q;else{int Nq=newnode (t[p].mx+1); memcpy (t[ Nq].go,t[q].go,sizeof (T[q].go)); T[nq].par=t[q].par;t[q].par=t[np].par=nq;for (;p &&t[p].go[c]==q;p=t[p]. PAR) t[p].go[c]=nq;}} LAST=NP;} int v[n],q[n];void precompute () {memset (v,0,sizeof (v)); for (int i=1;i<=size;++i) ++v[t[i].mx];for (int i=1;i<= size;++i) v[i]+=v[i-1];for (int i=size;i;--i) q[v[t[i].mx]--]=i;t[0].mx=-1;} void Max (int x,int data) {Max1[x]=max (max1[x],data); if (Max1[x]>max0[x]) swap (max1[x],max0[x]);} void Min (int x,int data) {min1[x]=min (min1[x],data); if (Min1[x]<min0[x]) swap (min1[x],min0[x]);} void Solve (ll *cnt,ll *maxv) {for (int i=size;i;--i) {if (t[u].rights>1) {Maxv[t[u].mx]=max (Maxv[t[u].mx],max (LL) Max0[u]*max1[u], (LL) min0[u]*min1[u]); ll tmp= (LL) t[u].rights* (t[u].rights-1)/2;cnt[t[u].mx]+=tmp;cnt[t[t[u].par ].mx]-=tmp;} T[t[u].par].rights+=t[u].rights; Max (T[u].par,max0[u]); Max (T[u].par,max1[u]); Min (T[u].par,min0[u]); Min (T[u].par,min1[u]);}}} Sam;char st[n];int a[n],n;ll cnt[n],ans[n];int Main () {n=read (); for (int i=1;i<=n;++i) ST[I]=READCH (), for (int i=1 ; i<=n;++i) A[i]=read (); Sam.clear (); for (int i=n;i;--i) sam.extend (St[i],a[i]); Sam.precompute (); memset (ans,128, sizeof (ANS)); Memset (cnt,0,sizeof (CNT)); Sam.solve (Cnt,ans); for (int i=n-1;i>=0;--i) cnt[i]+=cnt[i+1];for (int i= N-1;i>=0;--i) Ans[i]=max (ans[i],ans[i+1]); for (int i=n-1;i>=0;--i) if (!cnt[i]) ans[i]=0;for (int i=0;i<n;++i ) printf ("%lld%lld\n", Cnt[i],ans[i]); return 0;}
BZOJ4199:NOI2015D2T2 Wine Tasting Conference (Sam Edition)