首页 > 其他 > 详细

SP8222 NSUBSTR - Substrings

时间:2019-08-28 21:07:12      阅读:78      评论:0      收藏:0      [点我收藏+]

题面

https://www.luogu.org/problem/SP8222

题解

建出后缀树之后随便搞一搞,反向更新就好。

#include<cstdio>
#include<iostream>
#include<cstring>
#define ri register int
#define N 250050
using namespace std;

char s[N];
int ans[N];
struct SAM{
  int ff[N<<1],len[N<<1],cnt[N<<1];
  int ch[N<<1][26];
  int ton[N<<1],c[N<<1];
  int last,tot;
  inline void init() {
    last=tot=1;
  }
  inline void extend(int c) {
    int p=last,np=++tot; last=np;
    len[np]=len[p]+1;
    while (p && !ch[p][c]) ch[p][c]=np,p=ff[p];
    if (!p) ff[np]=1;
    else {
      int q=ch[p][c];
      if (len[p]+1==len[q]) {
        ff[np]=q;
      }
      else {
        int nq=++tot;
        for (ri i=0;i<26;i++) ch[nq][i]=ch[q][i]; ff[nq]=ff[q];
        len[nq]=len[p]+1;
        ff[np]=ff[q]=nq;
        while (p && ch[p][c]==q) ch[p][c]=nq,p=ff[p];
      }
    }
    cnt[np]++;
  }
  void work() {
    for (ri i=1;i<=tot;i++) ton[len[i]]++;
    for (ri i=1;i<=tot;i++) ton[i]+=ton[i-1];
    for (ri i=1;i<=tot;i++) c[ton[len[i]]--]=i;
    for (ri i=tot;i>=1;i--) cnt[ff[c[i]]]+=cnt[c[i]];
    for (ri i=1;i<=tot;i++) ans[len[i]]=max(ans[len[i]],cnt[i]);
  }
} sam;
int main(){
  scanf("%s",s+1);
  sam.init();
  for (ri i=1,l=strlen(s+1);i<=l;i++) sam.extend(s[i]-a);
  sam.work();
  for (ri i=strlen(s+1)-1;i>=1;i--) {
    ans[i]=max(ans[i],ans[i+1]);
  }
  for (ri i=1,l=strlen(s+1);i<=l;i++) printf("%d\n",ans[i]);
  return 0;
}

 

SP8222 NSUBSTR - Substrings

原文:https://www.cnblogs.com/shxnb666/p/11426287.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!