题意:给你一个字符串,要你输出1-len的字串出现的最大次数。
/** @xigua */ #include <stdio.h> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <cstring> #include <queue> #include <set> #include <string> #include <map> #include <climits> #define PI acos(-1) #define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a)) #define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a)) #define CLR(x) memset(x, 0, sizeof(x)) #define sf scanf #define pf printf using namespace std; typedef long long ll; typedef double db; const int maxn = 250005*2 + 1000; const int ma = 1e5 + 1000; const int mod = 1e9 + 7; const int INF = 1e8 + 5; const ll inf = 1e17 + 5; const db eps = 1e-6; const int MAXN = 2e5+1e3; struct SAM{ int ch[maxn<<1][26]; int fa[maxn<<1], len[maxn<<1]; int cnt, last, root; void init() { root=1; memset(ch, 0, sizeof(ch)); memset(fa, 0, sizeof(fa)); last=cnt=root; } void add(int c) { int p=last, np=last=++cnt; len[np]=len[p]+1; while(!ch[p][c] && p) { ch[p][c]=np; p=fa[p]; } if (p==0) fa[np]=1; else { int q = ch[p][c]; if(len[p] + 1 == len[q]) { fa[np] = q; } else { int nq = ++cnt; len[nq] = len[p] + 1; memcpy(ch[nq], ch[q], sizeof ch[q]); fa[nq] = fa[q]; fa[q] = fa[np] = nq; while(ch[p][c] == q && p) { ch[p][c] = nq; p = fa[p]; } } } } int find(char *s) { int p=root, l=0, c=0; int lenn=strlen(s); for(int i = 0; i < lenn; i++) { if(ch[p][s[i] - 'a']) { p = ch[p][s[i] - 'a']; c++; } else { while(p&&!ch[p][s[i]-'a']) p=fa[p]; if (!p) c=0, p=1; else c=len[p]+1, p=ch[p][s[i]-'a']; } l = max(l, c); } printf("%d\n", l); } }sam; char s[maxn]; int c[maxn<<1], pt[maxn<<1], f[maxn]; void innt() { memset(pt, 0, sizeof(pt)); memset(c, 0, sizeof(c)); memset(f, 0, sizeof(f)); } void top() { for (int i=1; i<=sam.cnt; i++) c[sam.len[i]]++; for (int i=1; i<=sam.cnt; i++) c[i]+=c[i-1]; for (int i=sam.cnt; i>=1; i--) pt[c[sam.len[i]]--]=i; // /*拓扑排序*/ // /*每个子串对应相应的pt*/ } int dp[maxn]; void solve() { innt(); scanf("%s", s); int lenn=strlen(s); sam.init(); for (int i=0; i<lenn; i++) { sam.add(s[i]-'a'); } top(); memset(dp, 0, sizeof(dp)); int p=sam.root; for (int i=0; i<lenn; i++) { p=sam.ch[p][s[i]-'a']; if (p) dp[p]++; //先找出所有子串令dp[p]=1 } for (int i=sam.cnt; i>=1; i--) { p=pt[i]; if (sam.fa[p]) dp[sam.fa[p]]+=dp[p]; /*该子串(a)还应加上作为串(aa)的个数*/ } for (int i=1; i<=sam.cnt; i++) { f[sam.len[i]]=max(f[sam.len[i]], dp[i]); } for(int i=lenn-1;i>=1;--i){ if (f[i]<f[i+1]) f[i]=f[i+1]; } for (int i=1; i<=lenn; i++) printf("%d\n", f[i]); } int main() { int t = 1, cas = 1; //freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); //scanf("%d", &t); while(t--) { // printf("Case %d: ", cas++); solve(); } return 0; }