NSUBSTR - Substrings
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba' that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.
Input
String S consists of at most 250000 lowercase latin letters.
Output
Output |S| lines. On the i-th line output F(i).
Example
Input:
ababa
Output:
3
2
2
11
题目大意:问这个字符串长度为1~len的子串出现的最大次数分别是多少
ac代码
![]()
#include<stdio.h> #include<stdlib.h> #include<string.h> #define max(a,b) (a>b?a:b) #define N 510005 struct sam { sam *pre,*son[26]; int len,g; }que[N],*root,*tail,*b[N]; int tot; void add(int c,int l) { sam *p=tail,*np=&que[tot++]; np->len=l; tail=np; while(p&&p->son[c]==NULL) { p->son[c]=np; p=p->pre; } if(p==NULL) np->pre=root; else { sam *q=p->son[c]; if(p->len+1==q->len) np->pre=q; else { sam *nq=&que[tot++]; *nq=*q; nq->len=p->len+1; np->pre=q->pre=nq; while(p&&p->son[c]==q) { p->son[c]=nq; p=p->pre; } } } } char str[N>>1]; int dp[N>>1]; int main() { while(scanf("%s",str)!=EOF) { int len=strlen(str); tot=0; root=tail=&que[tot++]; int i,j; for(i=0;i<len;i++) add(str[i]-'a',i+1); int cnt[N>>1]; memset(cnt,0,sizeof(cnt)); for(i=0;i<tot;i++) cnt[que[i].len]++; for(i=1;i<=len;i++) cnt[i]+=cnt[i-1]; for(i=0;i<tot;i++) b[--cnt[que[i].len]]=&que[i]; for(i=0;i<len;i++) { (root=root->son[str[i]-'a'])->g++; //root->g++; } memset(dp,0,sizeof(dp)); for(i=tot-1;i>=0;i--) { dp[b[i]->len]=max(dp[b[i]->len],b[i]->g); if(b[i]->pre) b[i]->pre->g+=b[i]->g; } for(i=len-1;i>0;i--) dp[i]=max(dp[i],dp[i+1]); for(i=1;i<=len;i++) printf("%d\n",dp[i]); } }