SP8222 NSUBSTR - Substrings

题面

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;
}

 

转载于:https://www.cnblogs.com/shxnb666/p/11426287.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值