ansj=min (j-i+1) hi<=j; tree-like array maintenance
Ansj=min (hi-i+1) i<=j,hi>=j; segment tree maintenance or monotonic queue.
When the hx-x
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm>const int len (100000) , LIMT (255); int Str[len+10],sfa[len+10],rank[len+10],height[len+10];int Tmp[len+10],p[len+10],cnt[len+10];int n,c[ Len+10],ans[len+10],q[len+10],li,hi;char ch[len+10];struct data{int x, y;} H[len+10];int max (int a,int b) {return a>b?a:b;} int min (int a,int b) {return a<b?a:b;} bool COM (int x,int y,int l) {return (Rank[x]==rank[y]) && (Rank[x+l]==rank[y+l]);} void doubling () {for (int i=1;i<=n;i++) {rank[i]=str[i];sfa[i]=i;} for (int pos=0,l=0,sigma=limt;pos<n;sigma=pos) {pos=0;for (int i=n-l+1;i<=n;i++) p[++pos]=i;for (int i=1;i<=n ; i++) if (sfa[i]>l) P[++pos]=sfa[i]-l;memset (cnt,0,sizeof (int) * (sigma+1));p os=0;for (int i=1;i<=n;i++) cnt[ rank[i]]++;for (int i=1;i<=sigma;i++) cnt[i]+=cnt[i-1];for (int i=n;i>=1;i--) sfa[cnt[rank[p[i]]]--]=p[i];for ( int i=1;i<=n;i++) tmp[sfa[i]]=com (sfa[i],sfa[i-1],l)? pos:++pos;for (int i=1;i<=n;i++) rank[i]=tmp[i];l=!l?1:l <<1;} For(int i=1;i<=n;i++) rank[sfa[i]]=i;for (int i=1,k,j;i<=n;i++) {k=sfa[rank[i]-1];if (!k) continue;j=height[rank[ I-1]];if (j) j--;while (Str[i+j]==str[k+j]) j++;height[rank[i]]=j;} int query (int x) {int sum=0;for (;x;x-=x& (x)) Sum=max (sum,c[x]); return sum;} void put (int x,int y) {for (;x<=n;x+=x& (x)) C[x]=max (c[x],y);} int main () {freopen ("c.in", "R", stdin), Freopen ("C.out", "w", stdout), scanf ("%s", ch), N=strlen (CH); for (int i=1;i<=n ; i++) str[i]=ch[i-1]-' a ' +1;doubling (); for (int i=1;i<=n;i++) {H[i].x=i+max (height[rank[i]],height[rank[i]+1]); h [I].y=i;if (h[i].x>n+1) printf ("NO");} for (int i=1,t;i<=n;i++) {if (h[i].x!=n+1) Ans[h[i].y]=h[i].x-h[i].y+1;else ans[h[i].y]=n;t=query (H[I].Y), if (t) Ans[h[i].y]=min (H[i].y-t+1,ans[h[i].y]); if (h[i].x!=n+1) put (H[I].X,H[I].Y);} q[li=1]=1;hi=1;for (int i=2;i<=n;i++) {while (H[q[hi]].x<i&&hi<=li) hi++;if (hi<=li&&h[q [Hi]]. x>=i&&h[q[hi]].x!=n+1) Ans[h[i].y]=min (ans[h[i].y],h[q[hi]].x-h[q[hi]].y+1), if (h[i].x!=n+1) {while (h[ Q[li]]. X-h[q[li]].y>h[i].x-h[i].y&&li>=hi) li--;q[++li]=i;}} for (int i=1;i<=n;i++) printf ("%d\n", Ans[i]); return 0;}
Bzoj 1396: Identify substring sa+ tree array + monotone queue