P3809 【模板】后缀排序
2017-07-31 17:33
267 查看
P3809 【模板】后缀排序
题目背景
这是一道模板题。
题目描述
读入一个长度为 nn 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 11 到 nn。
输入输出格式
输入格式:
一行一个长度为 nn 的仅包含大小写英文字母或数字的字符串。
输出格式:
一行,共n个整数,表示答案。
输入输出样例
输入样例#1:ababa输出样例#1:
5 3 1 4 2
说明
n <= 10^6n<=106
code
本题代码
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N = 1000100; char s ; int sa ,t1 ,t2 ,c ,rnk ,height ; //sa[i] 排名为i的是谁 -下标 //rnk[i] i的排名 -名次 //height[i] 排名为i的后缀与排名为i-1的后缀的最长公共前缀长度 int n,m = 130; void get_sa() { int *x = t1,*y = t2; //基数排序 for (int i=0; i<m; ++i) c[i] = 0; for (int i=0; i<n; ++i) c[x[i] = s[i]]++; for (int i=1; i<m; ++i) c[i] += c[i-1]; for (int i=n-1; i>=0; --i) sa[--c[x[i]]] = i; /* 每次循环 都将两个长度k子串合并为一个长度为2k的串 其中前k个字符构成的子串的排名为第一关键字,后k个字符为第二关键字 并求出合并后的字符串的排名 */ //每次排名得到一共有多少个排名p,由p优化m的值,节省空间。 for (int k=1; k<=n; k<<=1) { int p = 0; /* y数组是第二关键字排序的结果, 存储的是2k长度的字符串的第一关键字的下标 */ /* n-k到n-1中所有的元素第二关键字为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) c[i] = 0; for (int i=0; i<n; ++i) c[x[y[i]]]++; for (int i=1; i<m; ++i) c[i] += c[i-1]; for (int i=n-1; i>=0; --i) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for (int i=1; i<n; ++i) x[sa[i]] = (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]) ? p-1 : p++; if (p >= n) break; m = p; } } void get_height() { for (int i=0; i<n; ++i) rnk[sa[i]] = i; // sa排名为i的下标,rnk[i]下标为i的后缀的名次。 int k = 0; height[0] = 0; /* 性质:height[rnk[i]] >= height[rnk[i-1]]-1 理解为起始下标为i的后缀和i-1的后缀除了开头第一个字符不同,其余的相同的 即suffix[i,n]与suffix[i-1,n]只有第一个字符不同。 所以suffix[i-1,n]匹配上的子串,与suffix[i,n]匹配的子串,中k-1个是相等的。 */ for (int i=0; i<n; ++i) { if (!rnk[i]) continue; if (k) k--; int j = sa[rnk[i]-1]; // 前一个排名的后缀的开始位置 while (i+k<n && j+k<n && s[i+k]==s[j+k]) k++; height[rnk[i]] = k; } } int main() { scanf("%s",s); n = strlen(s); get_sa(); for (int i=0; i<n; ++i) printf("%d ",sa[i]+1); return 0; }View Code
相关文章推荐
- 【后缀数组】洛谷P3809模板题
- 洛谷.3809.[模板]后缀排序(后缀数组 倍增)
- UOJ #35. 后缀排序(后缀数组模板题)
- UOJ #35. 后缀排序 后缀数组模板题
- 【UOJ #35】后缀排序 后缀数组模板
- P3809 【模版】后缀排序
- UOJ #35. BZOJ 1031 后缀排序 后缀数组模板
- luogu P3809 【模板】后缀排序
- 洛谷P3809 【模板】后缀排序
- luogu P3809 【模板】后缀排序
- luogu #3809 【模板】后缀排序(后缀数组)
- [洛谷P3809]【模板】后缀排序
- 【模板题】后缀排序
- UOJ.35.[模板]后缀排序(后缀数组 倍增)
- 后缀数组(一)(模板题poj2774)
- <学习笔记>排序模板
- 第14周项目一排序函数模板
- 快速排序----模板实现
- 【模板整合】SAM后缀自动机的构建
- java 利用泛性和反射机制实现collections.sort排序模板