倍长该串建立后缀自动机,即求字典序最小的子串,暴力跑即可。
1 #include<cstdio> 2 #include<cstring> 3 #define N 10005 4 #define calc(k) (len[k]-len[fa[k]]) 5 int V,last,n,a[N],id[N<<2],mi[N<<2],len[N<<2],sum[N<<2],fa[N<<2],ch[N<<2][31]; 6 char s[N]; 7 void add(int c){ 8 int p=last,np=last=++V; 9 len[np]=len[p]+1; 10 for(;(p)&&(!ch[p][c]);p=fa[p])ch[p][c]=V; 11 if (!p)fa[np]=1; 12 else{ 13 int q=ch[p][c]; 14 if (len[q]==len[p]+1)fa[np]=q; 15 else{ 16 int nq=++V; 17 len[nq]=len[p]+1; 18 memcpy(ch[nq],ch[q],sizeof(ch[q])); 19 fa[nq]=fa[q]; 20 fa[np]=fa[q]=nq; 21 for(;(p)&&(ch[p][c]==q);p=fa[p])ch[p][c]=nq; 22 } 23 } 24 } 25 int main(){ 26 scanf("%d",&n); 27 while (n--){ 28 scanf("%s",s); 29 memset(ch,0,sizeof(ch)); 30 memset(fa,0,sizeof(fa)); 31 memset(len,0,sizeof(len)); 32 V=last=1; 33 for(int i=0;s[i];i++)add(s[i]-'a'); 34 for(int i=0;s[i];i++)add(s[i]-'a'); 35 int l=strlen(s),k=1; 36 for(int i=0;s[i];i++) 37 for(int j=0;j<26;j++) 38 if (ch[k][j]){ 39 k=ch[k][j]; 40 break; 41 } 42 printf("%d\n",len[k]+1-l); 43 } 44 }