P3809 【模板】后缀排序

别说谁变了你拦得住时间么 提交于 2019-12-02 03:08:26

P3809 【模板】后缀排序

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e6+5;
 4 char s[maxn];
 5 int sa[maxn], t[maxn], t2[maxn], c[maxn];
 6 int n;
 7 //构造字符串s的后缀数组, 每个字符值必须为0 ~ m-1
 8 void build_sa(int m) {
 9     int *x = t, *y = t2;
10     //基数排序
11     for(int i = 0; i < m; i++) c[i] = 0;
12     for(int i = 0; i < n; i++) c[x[i] = s[i]]++;
13     for(int i = 1; i < m; i++) c[i] += c[i-1];
14     for(int i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
15     for(int k = 1; k <= n; k <<= 1) {
16         int p = 0;
17         //直接利用sa数组排序第二关键字
18         for(int i = n-k; i < n; i++) y[p++] = i;
19         for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
20         //基数排序第一关键字
21         for(int i = 0; i < m; i++) c[i] = 0;
22         for(int i = 0; i < n; i++) c[x[y[i]]]++;
23         for(int i = 1; i < m; i++) c[i] += c[i-1];
24         for(int i = n-1; i>= 0; i--) sa[--c[x[y[i]]]] = y[i];
25         //根据sa和y数组计算新的x数组
26         swap(x, y);
27         p = 1;
28         x[sa[0]] = 0;
29         for(int i = 1; i < n; i++)
30             x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++);
31         if(p >= n) break;
32         m = p;
33     }
34 }
35 int main() {
36     scanf("%s",s); n = strlen(s);
37     build_sa(123);
38     printf("%d",sa[0]+1);
39     for (int i = 1; i < n; i++)
40         printf(" %d",sa[i]+1);
41     printf("\n");
42     return 0;
43 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!