题目链接

论找到一个好的教程的正确性。。

后缀数组

下标从1编号:

//299ms	2560kb
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=1e5+5; int n,sa[N],rk[N],sa2[N],tm[N],ht[N];
char s[N]; void Get_SA()
{
int *x=rk,*y=sa2,m=200;
for(int i=0; i<=m; ++i) tm[i]=0;
for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+1];
for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
for(int i=n; i; --i) sa[tm[x[i]]--]=i;
for(int p=0,k=1; k<n; k<<=1,m=p,p=0)
{
for(int i=n-k+1; i<=n; ++i) y[++p]=i;
for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
for(int i=0; i<=m; ++i) tm[i]=0;
for(int i=1; i<=n; ++i) ++tm[x[i]];
for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i]; std::swap(x,y), p=1, x[sa[1]]=1;
for(int i=2; i<=n; ++i)
// if(y[sa[i-1]]==y[sa[i]]&&((sa[i-1]+k<=n&&sa[i]+k<=n&&y[sa[i-1]+k]==y[sa[i]+k])||(sa[i-1]+k>n&&sa[i]+k>n))) x[sa[i]]=p;
// if(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]) x[sa[i]]=p;
// else x[sa[i]]=++p;
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
if(p>=n) break;
}
}
void Calc_ht()
{
for(int i=1; i<=n; ++i) rk[sa[i]]=i;
ht[1]=0;
for(int k=0,p,i=1; i<=n; ++i)//ht[rk[i]]>=ht[rk[i-1]]-1
{
if(rk[i]==1) continue;//排名为0的 ht[rk[i]]=ht[0]=0
if(k) --k;
p=sa[rk[i]-1];
while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
ht[rk[i]]=k;
}
} int main()
{
scanf("%s",s+1), n=strlen(s+1);
Get_SA();
for(int i=1; i<=n; ++i) printf("%d ",sa[i]);
putchar('\n'), Calc_ht();
for(int i=2; i<=n; ++i) printf("%d ",ht[i]); return 0;
}
//321ms	2552kb
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=1e5+5; int n,sa[N],rk[N],sa2[N],tm[N],ht[N];
char s[N]; void Get_SA()
{
int *x=rk,*y=sa2,m=28;
for(int i=0; i<m; ++i) tm[i]=0;
for(int i=0; i<n; ++i) ++tm[x[i]=s[i]-'a'];
for(int i=1; i<m; ++i) tm[i]+=tm[i-1];
for(int i=n-1; ~i; --i) sa[--tm[x[i]]]=i;
for(int p=0,k=1; k<n; k<<=1,/*m=p,*/m=p+1,p=0)
{
for(int i=n-k; i<n; ++i) y[p++]=i; for(int i=0; i<n; ++i) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=0; i<m; ++i) tm[i]=0;
for(int i=0; i<n; ++i) ++tm[x[i]];
for(int i=1; i<m; ++i) tm[i]+=tm[i-1];
for(int i=n-1; ~i; --i) sa[--tm[x[y[i]]]]=y[i]; // std::swap(x,y), p=1, x[sa[0]]=0;
// for(int i=1; i<n; ++i)
// if(y[sa[i-1]]==y[sa[i]]&&((sa[i-1]+k<n&&sa[i]+k<n&&y[sa[i-1]+k]==y[sa[i]+k])||(sa[i-1]+k>=n&&sa[i]+k>=n))) x[sa[i]]=p-1;
// else x[sa[i]]=p++;
// if(p>=n) break;
std::swap(x,y), p=0, x[sa[0]]=0;
for(int i=1; i<n; ++i)
if(y[sa[i-1]]==y[sa[i]]&&((sa[i-1]+k<n&&sa[i]+k<n&&y[sa[i-1]+k]==y[sa[i]+k])||(sa[i-1]+k>=n&&sa[i]+k>=n))) x[sa[i]]=p;
else x[sa[i]]=++p;
if(p+1>=n) break;
}
}
void Calc_ht()
{
for(int i=0; i<n; ++i) rk[sa[i]]=i;
ht[0]=0;
for(int k=0,p,i=0; i<n; ++i)//ht[rk[i]]>=ht[rk[i-1]]-1
{
if(!rk[i]) continue;//排名为0的 ht[rk[i]]=ht[0]=0
if(k) --k;
p=sa[rk[i]-1];
while(i+k<n&&p+k<n&&s[i+k]==s[p+k]) ++k;
ht[rk[i]]=k;
}
} int main()
{
scanf("%s",s), n=strlen(s);
Get_SA();
for(int i=0; i<n; ++i) printf("%d ",sa[i]+1);
putchar('\n'), Calc_ht();
for(int i=1; i<n; ++i) printf("%d ",ht[i]); return 0;
}

UOJ.35.[模板]后缀排序(后缀数组 倍增)的更多相关文章

  1. UOJ #35. 后缀排序 后缀数组 模板

    http://uoj.ac/problem/35 模板题,重新理了一遍关系.看注释吧.充分理解了倍增的意义,翻倍之后对上一次排序的利用是通过一种类似于队列的方式完成的. #include<ios ...

  2. UOJ #35. 后缀排序[后缀数组详细整理]

    #35. 后缀排序 统计 描述 提交 自定义测试 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符 ...

  3. 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记

    题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...

  4. Uoj #35. 后缀排序(后缀数组)

    35. 后缀排序 统计 描述 提交 自定义测试 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在 ...

  5. Codevs 1500 后缀排序(后缀数组)

    1500 后缀排序 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个 ...

  6. 【UOJ #35】后缀排序 后缀数组模板

    http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...

  7. [UOJ#35] [UOJ后缀数组模板题] 后缀排序 [后缀数组模板]

    后缀数组,解决字符串问题的有利工具,本题代码为倍增SA算法 具体解释详见2009年国家集训队论文 #include <iostream> #include <algorithm> ...

  8. Luogu P3809 【模板】后缀排序(后缀数组板题)

    忘完了- emmm-

  9. luogu3809 后缀排序 后缀数组

    ref and 挑战程序设计竞赛. 主要是发现自己以前写得代码太难看而且忘光了,而且我字符串死活学不会啊,kmp这种东西我都觉得是省选+难度啊QAQ #include <iostream> ...

随机推荐

  1. bzoj 1002

    表示我这种蒟蒻面对这种递推第一思想显然是打表啊 先贴个用来打表的暴力: #include <cstdio> struct node {     int l,r; }p[]; ]; ]; i ...

  2. 官方版sublime Text3汉化和激活注册码

    转载:https://www.cnblogs.com/chaonuanxi/p/9371837.html sublimeText3 很不错,前面几天下了vscore学习Node.js,感觉有点懵,今天 ...

  3. easyui合并多个单元格

    $('#table-v2').datagrid({ url: './data/am/data1_table.json', pagination: true, //显示分页 fit: true, //d ...

  4. python目录和文件的列表清单

    import os # 通过给定的文件夹,列举出这个文件夹当中,所有的文件,以及文件夹,子文件夹当中的所有文件def listFilesToTxt(dir,file): # 1.列举出,当前给定的文件 ...

  5. windows环境下永久修改pip镜像源的方法(转)

    一.在windows环境下修改pip镜像源的方法(以python3.7为例) (1):在windows文件管理器中,输入 %APPDATA%,cmd里面输入即可. (2):会定位到一个新的目录下,在该 ...

  6. 指定的参数已超出有效值的范围。参数名:sit ,先仔细看看错误和我的一样不一样

    控制面板>程序>

  7. DapperHelper 帮助类

    using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...

  8. k8s 1.12.6版的kubeadm默认配置文件

    这个对于提高安装配置的便捷性,相当有帮助. 命令如下: kubeadm config print-default 输出如下: apiEndpoint: advertiseAddress: 1.2.3. ...

  9. Spring data JPA中使用Specifications动态构建查询

    有时我们在查询某个实体的时候,给定的条件是不固定的,这是我们就需要动态 构建相应的查询语句,在JPA2.0中我们可以通过Criteria接口查询,JPA criteria查询.相比JPQL,其优势是类 ...

  10. python安装plinter

    我下的python2.7是有pip的,但是直接在cmd中输入pip是无响应的.要去环境变量中配置D:/python/Script 这样就可以了. pip install splinter就能下载了