Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings:
String Rank
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
String Rank
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
abcder aaaaaa ababab
1 1 6 1 1 6 1 6 1 3 2 3
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N = 1000005;
char str[N];
int Next[N];
void getNext(char p[],int m,int Next[]){
int i=0;
int t=-1;
Next[0]=-1;
while(i<m){
if(t<0||p[i]==p[t])
Next[++i]=++t;
else t=Next[t];
}
}
int min_max_expree(char str[],int len,int flag){
int i=0,j=1,k=0;
while(i<len&&j<len&&k<len){
int t=str[(j+k)%len]-str[(i+k)%len];
if(t==0) k++;
else{
if(flag){
if(t>0) j+=k+1;
else i+=k+1;
}
else{
if(t>0) i+=k+1;
else j+=k+1;
}
if(i==j) j++;
k=0;
}
}
return min(i,j);
}
int main(){
while(scanf("%s",str)!=EOF){
int len=strlen(str);
int min_express=min_max_expree(str,len,1);
int max_express=min_max_expree(str,len,0);
getNext(str,len,Next);
int l=len-Next[len];
int ans=len%l?1:len/l;
printf("%d %d %d %d\n",min_express+1,ans,max_express+1,ans);
}
return 0;
}