哈希:
#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;
}
京公网安备 11010502036488号