zoukankan      html  css  js  c++  java
  • 后缀数组学习笔记

    现在来看倍增算法是非常好理解的。

    直接放一篇blog写的挺好的:http://www.cnblogs.com/zinthos/p/3899725.html

    虽然理论复杂度是$O(nlogn)$,但其中各种细节优化确实十分有必要的。

    给自己放一个倍增的模板,有空填DC3的坑

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 int n,m;
     6 char s[1000010];
     7 int rk[1000010],sa[1000010],tmp[1000010],c[1000010];
     8 void outint(int x){
     9     if(x>=10) outint(x/10);
    10     putchar(x%10+'0');
    11 }
    12 bool inline cmp(int *r,int a,int b,int l){
    13     return r[a]==r[b]&&r[a+l]==r[b+l];
    14 }
    15 void Getsa(){
    16     m=127;
    17     for(int i=0;i<=m;i++) c[i]=0;
    18     for(int i=1;i<=n;i++) c[rk[i]=s[i]]++;
    19     for(int i=1;i<=m;i++) c[i]+=c[i-1];
    20     for(int i=n;i>=1;i--) sa[c[rk[i]]--]=i;
    21     for(int i=1;i<=n;i<<=1){
    22         int p=0;
    23         for(int j=n-i+1;j<=n;j++) tmp[++p]=j;
    24         for(int j=1;j<=n;j++) if(sa[j]>i) tmp[++p]=sa[j]-i;
    25         for(int j=0;j<=m;j++) c[j]=0;
    26         for(int j=1;j<=n;j++) c[rk[tmp[j]]]++;
    27         for(int j=1;j<=m;j++) c[j]+=c[j-1];
    28         for(int j=n;j>=1;j--) sa[c[rk[tmp[j]]]--]=tmp[j];
    29         swap(rk,tmp);
    30         rk[sa[1]]=p=1;
    31         for(int j=2;j<=n;j++) rk[sa[j]]=cmp(tmp,sa[j],sa[j-1],i)?p:++p;
    32         if(p>=n) break;
    33         m=p;
    34     }
    35 }
    36 int main(){
    37     scanf("%s",s+1);
    38     n=strlen(s+1);
    39     Getsa();
    40     for(int i=1;i<=n;i++){
    41         outint(sa[i]);
    42         putchar(' ');
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    ngix反向代理-之反向
    redux和flux究竟有什么不同, 说点自己的理解
    npm发包记录
    由一个聚焦-focus-事件异常跟踪引起的总结
    git查看分支的几个方法
    test-your-mind-快速测试自己的代码
    contos7 yum安装php7.2与swoole (2)
    php_ thinkphp 时间回滚
    30个php操作redis常用方法代码例子
    redis_php 安装与卸载
  • 原文地址:https://www.cnblogs.com/halfrot/p/7474979.html
Copyright © 2011-2022 走看看