• 【SPOJ】LCS2


    题面

    https://vjudge.net/problem/SPOJ-LCS2

    题解

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ri register int
    #define N 100050
    using namespace std;
    
    char ss[N];
    char s[N];
    int ans[N<<1];
    
    struct SAM {
      int ff[N<<1],len[N<<1];
      int ch[N<<1][26];
      int dp[N<<1];
      int ton[N<<1],c[N<<1];
      int tot,last;
      inline void clear() {
        tot=last=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[q]==len[p]+1) {
            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];
          }
        }
      }
      void getsa(){
        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;
      }
      void match() {
        memset(dp,0,sizeof(dp));
        int now=1,cnt=0;
        for (ri i=1,l=strlen(s+1);i<=l;i++) {
          if (ch[now][s[i]-'a']) {
            cnt++;
            now=ch[now][s[i]-'a'];
            if (cnt>dp[now]) dp[now]=cnt;
          }
          else {
            while (now && !ch[now][s[i]-'a']) now=ff[now];
            if (!now) {
              cnt=0;
              now=1;
              continue;
            }
            else {
              if (len[now]>dp[now]) dp[now]=len[now];
              cnt=len[now]+1;
              now=ch[now][s[i]-'a'];
              if (cnt>dp[now]) dp[now]=cnt;
            }
          }
        }
        for (ri i=tot;i>=1;i--) if (dp[c[i]]) dp[ff[c[i]]]=len[ff[c[i]]];
        for (ri i=1;i<=tot;i++) ans[i]=min(ans[i],dp[i]);
      }
    } sam;
    
    int main(){
      scanf("%s",ss+1);
      sam.clear();
      for (ri i=1,l=strlen(ss+1);i<=l;i++) sam.extend(ss[i]-'a');
      sam.getsa();
      memset(ans,0x3f,sizeof(ans));
      while (scanf("%s",s+1)==1) sam.match();
      int ret=0;
      for (ri i=1;i<=sam.tot;i++) if (ans[i]>ret) ret=ans[i];
      printf("%d
    ",ret);
    }
  • 相关阅读:
    「V 曲闲谈」《宠儿》——谁凌迟着梦想家
    Diary 「NOI 2022」尘降
    Solution 「OurOJ #47407」巧立名目
    Solution 「NOI 2017」「洛谷 P3824」泳池
    「V 曲闲谈」《hello&bye,days》——记这周
    Solution 「NEERC 2016」Delight for a Cat 的一个尝试
    「LOJ2461」完美的队列
    数学杂谈 #20
    「CF850F」Rainbow Balls
    「BZOJ3569」DZJ Loves Chinese II
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279172.html
Copyright © 2020-2023  润新知