Max Substring
Time limit:
1000 ms
Memory limit: 256 MB
Memory limit: 256 MB
You are given a string S. Find a string T that has the most number of occurrences as a substring in S.
If the solution is not unique, you should find the one with maximum length. If the solution is still not unique, find the smallest lexicographical one.
Standard input
The first line contains string S.
Standard output
Print string T on the first line.
Constraints and notes
- S consists of lowercase letters of the English alphabet
- The length of S is between 1 and 105
Input | Output | Explanation |
---|---|---|
cabdab | ab |
|
cabcabc | c |
|
ababababab | ab |
Note that we're interested in substrings(continuous) not subsequences.
|
code:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=1000000;
int rankk[maxn],sa[maxn],height[maxn],tmp[maxn],cnt[maxn];
char s[maxn];
void suff(int n,int m)
{
int i,j,k;
n++;
// printf("%d %d\n",n,m);
for(i=0; i<n+10; i++)
rankk[i]=sa[i]=height[i]=tmp[i]=0;
for(i=0; i<m; i++)
cnt[i]=0;
for(i=0; i<n; i++)cnt[rankk[i]=s[i]]++;
for(i=1; i<m; i++)
cnt[i]+=cnt[i-1];
for(i=0; i<n; i++)
sa[--cnt[rankk[i]]]=i;
for(k=1; k<=n; k<<=1)
{
for(i=0; i<n; i++)
{
j=sa[i]-k;
if(j<0)
j+=n;
tmp[cnt[rankk[j]]++]=j;
}
sa[tmp[cnt[0]=0]]=j=0;
for(i=1; i<n; i++)
{
if(rankk[tmp[i]]!=rankk[tmp[i-1]]||rankk[tmp[i]+k]!=rankk[tmp[i-1]+k])
cnt[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rankk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if(j>=n-1)
break;
}
for(j=rankk[height[i=k=0]=0]; i<n-1; i++,k++)
while(~k&&s[i]!=s[sa[j-1]+k])
height[j]=k--,j=rankk[sa[j]+1];
}
int main()
{
int n;
scanf("%s",s);
n=strlen(s);
suff(n,'z'+1);
int changdu=inf,geshu=0;
int changduu=0,geshuu=0,biao=-1;
for(int i=0; i<=n; i++)
{
// printf("%d\n",height[i]);
if(height[i])
{
geshu++;
changdu=min(changdu,height[i]);
if(geshu>geshuu)
{
geshuu=geshu;
changduu=changdu;
biao=sa[i];
}
else if(geshu==geshuu)
{
if(changdu>changduu)
{
changduu=changdu;
biao=sa[i];
}
}
}
else
{
geshu=0;
changdu=inf;
}
}
if(biao==-1)
printf("%s",s);
else
for(int i=biao; i<min(n,biao+changduu); i++)
printf("%c",s[i]);
printf("\n");
}