HihoCoder - 1415 后缀数组

把a,b合并起来跑一遍就行

记录一下板子

#include<bits/stdc++.h>
#define ll long long 
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
//#define endl '\n'
#define pii pair<ll,ll>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next)
#define show(x) cout<<#x<<"="<<x<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showmm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<#x<<'['<<i<<']'<<'['<<j<<"]="<<x[i][j]<<(" \n"[j==b])
#define showm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<x[i][j]<<(" \n"[j==b])
#define showa1(x,a,b) cout<<#x<<":\n";rep(i,a,b) showa(x,i);cout<<endl
#define showa2(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl
using namespace std;//head
const int maxn=2e5+10,maxm=2e6+10;
const ll INF=0x3f3f3f3f,mod=1e9+7;
int casn,k;
namespace suffix{
  int tr[maxn],rank[maxn],sa[maxn],h[maxn];
  int has[maxn],bir[maxn],val[maxn],deep[maxn];
  int n;
  int cmp(int x,int y,int k){
    if(x+k>n||y+k>n)return 0;
    return rank[x]==rank[y]&&rank[x+k]==rank[y+k];
  }
  void getsa(int *s,int _n,int m=maxn-5){
    int i,cnt;n=_n;
    for(i=1;i<=n;i++)has[s[i]]++;
    for(i=1,cnt=0;i<=m;i++)if(has[i])tr[i]=++cnt;
    for(i=1;i<=m;i++)has[i]+=has[i-1];
    for(i=1;i<=n;i++)rank[i]=tr[s[i]],sa[has[s[i]]--]=i;
    for(int k=1;cnt!=n;k<<=1){
      for(i=1;i<=n;i++)has[i]=0;
      for(i=1;i<=n;i++)has[rank[i]]++;
      for(i=1;i<=n;i++)has[i]+=has[i-1];
      for(i=n;i>=1;i--)if(sa[i]>k)tr[sa[i]-k]=has[rank[sa[i]-k]]--;
      for(i=1;i<=k;i++)tr[n-i+1]=has[rank[n-i+1]]--;
      for(i=1;i<=n;i++)sa[tr[i]]=i;
      for(i=1,cnt=0;i<=n;i++)tr[sa[i]]=cmp(sa[i],sa[i-1],k) ? cnt:++cnt;
      for(i=1;i<=n;i++)rank[i]=tr[i];
    }
    for(int i=1;i<=n;i++){
      if(rank[i]==1)continue;
      for(int j=max(1,h[rank[i-1]]-1);;j++){
        if(s[i+j-1]==s[sa[rank[i]-1]+j-1])h[rank[i]]=j;
        else break;
      }
    }
  }
  int solve(int len,int n){
    int ans=0;
//    showa2(h,1,len);
//    showa2(sa,1,len);
//    showa2(rank,1,len);
    rep(i,1,len) if((sa[i]<=n)^(sa[i-1]<=n))
        ans=max(ans,h[i]);
    return ans;
  }
}
char a[maxn],b[maxn];
int c[maxn<<1];
int main() {IO;
  cin>>(a+1)>>(b+1);
  int n=strlen(a+1),m=strlen(b+1);
  rep(i,1,n) c[i]=a[i];c[n+1]='z'+1;
  rep(i,1,m) c[i+n+1]=b[i];
  int len=n+m+1;
//  showa2(c,1,len);
//  show3(n,m,len);
  suffix::getsa(c,len,233);
  cout<<suffix::solve(len,n);
  return 0;
}

 

转载于:https://www.cnblogs.com/nervendnig/p/11431117.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值