luogu #3809 【模板】后缀排序(后缀数组)
2017-12-04 22:51
344 查看
题目背景
这是一道模板题。
题目描述
读入一个长度为n的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 1 1 到 n n。
输入输出格式
输入格式:
一行一个长度n 的仅包含大小写英文字母或数字的字符串。
输出格式:
一行,共n个整数,表示答案。
模板题,注释写的很详细了
这是一道模板题。
题目描述
读入一个长度为n的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 1 1 到 n n。
输入输出格式
输入格式:
一行一个长度n 的仅包含大小写英文字母或数字的字符串。
输出格式:
一行,共n个整数,表示答案。
模板题,注释写的很详细了
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000050 char s[maxn]; int t[maxn],sa[maxn],x[maxn],y[maxn],p,m=128,n; using namespace std; int main() { scanf("%s",s),n=strlen(s),s[n++]=0; //串尾加进一个最小的字符方便比较 for (int i=0;i<m;i++) t[i]=0; for (int i=0;i<n;i++) t[x[i]=s[i]]++; //装进桶 for (int i=1;i<m;i++) t[i]+=t[i-1]; //基数排序 for (int i=n-1;i>=0;i--) sa[--t[s[i]]]=i; for (int j=1;p<n;j<<=1,m=p) //j:当前倍增长度 { p=0; for (int i=n-j;i<n;i++) y[p++]=i; //显然,对于n-j<=i<n,i的第二关键字为0 for (int i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; //第二关键字排名为i的位置是y[i] for (int i=0;i<m;i++) t[i]=0; for (int i=0;i<n;i++) t[x[i]]++; for (int i=1;i<m;i++) t[i]+=t[i-1]; for (int i=n-1;i>=0;i--) sa[--t[x[y[i]]]]=y[i]; //与前面的排序相似,将元素以第二关键字中的排名的位置为顺序逐一出桶 swap(x,y),p=1; //将当前rank作为下一次倍增的第一关键字并保存 x[sa[0]]=0; //多加进的一个最小字符一定排在第0位,将其第一关键字设为0 for (int i=1;i<n;i++) if (y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]) x[sa[i]]=p-1;else x[sa[i]]=p++; //得出下一次的第一关键字数组 } for (int i=1;i<n;i++) printf("%d ",sa[i]+1); }
相关文章推荐
- UOJ.35.[模板]后缀排序(后缀数组 倍增)
- UOJ #35. 后缀排序(后缀数组模板题)
- UOJ #35. 后缀排序 后缀数组模板题
- 【UOJ #35】后缀排序 后缀数组模板
- 洛谷.3809.[模板]后缀排序(后缀数组 倍增)
- 6.对数组进行排序、求最大值和求元素和的函数采用静态成员函数的方式封装成数组算法类模板ArrayAlg,并采用相关数据进行测试。
- 后缀数组模板
- 后缀数组 模板
- 用模板写选择排序-数组
- POJ 1743 - Musical Theme 后缀数组模板+用后缀数组求不覆盖最长重复子序列
- 后缀数组模板
- SPOJ 694 Distinct Substrings 后缀数组 模板
- 对数组进行排序、求最大值和求元素和的算法都编写为函数模板,采用相关数据进行测试。
- P3809 【模板】后缀排序
- 后缀数组模板
- 后缀数组模板
- 用模板写选择排序-数组
- 后缀数组模板
- uoj#35 后缀排序(后缀数组模版)
- 后缀数组基数排序——bzoj3172: [Tjoi2013]单词