哈希: #include <bits/stdc++.h> using namespace std; #define LL long long const int maxn=1e6+10; LL mod[2]= {1610612741, 998244353}; LL base[2] ={131, 233}; LL p[2][maxn]; LL g[2][maxn]; void getp(){ p[0][0]=p[1][0]=1; for(int i=1; i<maxn; i++){ p[0][i]=p[0][i-1]*base[0]%mod[0]; p[1][i]=p[1][i-1]*base[1]%mod[1]; } } pair<LL, LL> Hash(char s[]){ int len=strlen(s+1); g[0][0]=0, g[0][1]=s[1]; g[1][0]=0, g[1][1]=s[1]; for(int i=2; i<=len; i++){ g[0][i]=(g[0][i-1]*base[0]+s[i])%mod[0]; g[1][i]=(g[1][i-1]*base[1]+s[i])%mod[1]; } return {g[0][len], g[1][len]}; } pair<LL, LL> getLR(int l, int r){ LL ans1=((g[0][r]-g[0][l-1]*p[0][r-l+1])%mod[0]+mod[0])%mod[0]; LL ans2=((g[1][r]-g[1][l-1]*p[1][r-l+1])%mod[1]+mod[1])%mod[1]; return {ans1, ans2}; } char s[maxn]; int pos[maxn]; int solve(int x, int y, int k){ int l=0, r=k, pos=0; while(l<=r){ int mid=(l+r)/2; if(getLR(x, x+mid-1)==getLR(y, y+mid-1)){ l=mid+1; pos=mid; } else{ r=mid-1; } } if(s[x+pos]<s[y+pos]) return 1; else return 0; } int main(){ getp(); int n, k; scanf("%d%d%s", &n, &k, s); for(int i=0; i<n; i++){ s[n+i]=s[i]; } Hash(s); for(int i=0; i<n; i++){ if(i<k) pos[i%k]=i; else{ if(solve(pos[i%k], i, k)){ pos[i%k]=i; } } } int ans=pos[0]; for(int i=1; i<k; i++){ if(!solve(ans, pos[i], k)){ ans=pos[i]; } } for(int i=0; i<k; i++){ printf("%c", s[ans+i]); } printf("\n"); return 0; } 后缀数组 #include <iostream> #include<algorithm> #include <stdio.h> #include <string.h> using namespace std; #define maxn 1000005 int wa[maxn],wb[maxn],wsf[maxn],wv[maxn],sa[maxn]; int rak[maxn],height[maxn], s[maxn]; char s1[maxn]; //sa:字典序中排第i位的起始位置在str中sa[i] sa[1~n]为有效值 //rank:就是str第i个位置的后缀是在字典序排第几 rank[0~n-1]为有效值 //height:字典序排i和i-1的后缀的最长公共前缀 height[1~n]为有效值,第1个到最后一个 int cmp(int *r,int a,int b,int k) { return r[a]==r[b]&&r[a+k]==r[b+k]; } void getsa(int *r,int *sa,int n,int m){//n为添加0后的总长 int i,j,p,*x=wa,*y=wb,*t; for(i=0; i<m; i++) wsf[i]=0; for(i=0; i<=n; i++) wsf[x[i]=r[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n; i>=0; i--) sa[--wsf[x[i]]]=i; p=1; j=1; for(; p<=n; j*=2,m=p) { for(p=0,i=n+1-j; i<=n; i++) y[p++]=i; for(i=0; i<=n; i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0; i<=n; i++) wv[i]=x[y[i]]; for(i=0; i<m; i++) wsf[i]=0; for(i=0; i<=n; i++) wsf[wv[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n; i>=0; i--) sa[--wsf[wv[i]]]=y[i]; t=x; x=y; y=t; x[sa[0]]=0; for(p=1,i=1; i<=n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++; } } void getheight(int *r,int n)//n为添加0后的总长 { int i,j,k=0; for(i=1; i<=n; i++) rak[sa[i]]=i; for(i=0; i<n; i++) { if(k) k--; else k=0; j=sa[rak[i]-1]; while(r[i+k]==r[j+k]) k++; height[rak[i]]=k; } } void pus(int len){ puts("--------------All Suffix--------------"); for (int i = 0; i < len; ++i) { printf("%d:\t", i); for (int j = i ; j < len; ++j) printf("%c", s1[j]); puts(""); } puts(""); puts("-------------After sort---------------"); for (int i = 1; i <= len; ++i) { printf("sa[%2d ] = %2d\t", i, sa[i]); for (int j = sa[i]; j < len; ++j) printf("%c", s1[j]); puts(""); } puts(""); puts("---------------Height-----------------"); for (int i = 1; i <= len; ++i) printf("height[%2d ]=%2d \n", i, height[i]); puts(""); puts("----------------Rank------------------"); for (int i = 0; i < len; ++i) printf("Rank[%2d ] = %2d\n", i, rak[i]); puts("------------------END-----------------"); } int mx[maxn], pos[maxn]; int main() { int n, k; scanf("%d%d%s", &n, &k, s1); int len=strlen(s1), tot=0; for(int i=0; i<len; i++){ s1[len+i]=s1[i]; } len*=2; for(int i=0; i<len; i++){ s[tot++]=s1[i]-'a'+1; } s[tot]=0; getsa(s,sa,tot,5000); getheight(s,tot); //pus(tot); for(int i=0; i<len; i++){ if(rak[i]>mx[i%k]){ mx[i%k]=rak[i]; pos[i%k]=i; } } int ans=pos[0]; for(int i=1; i<k; i++){ if(rak[pos[i]]<rak[ans]){ ans=pos[i]; } } for(int i=ans; i<ans+k; i++){ printf("%c", s1[i]); } printf("\n"); return 0; }