标签:后缀 tax rak tp int MAXN 笔记 数组 sa
dalao的博客,讲的很详细
倍增法:设当前已知各后缀的前 \(2^k\) 个字符的相对大小关系(即排名数组 \(rank\)), 于是只要用 \((rank[i], rank[i + 2 ^k])\) 进行双关键字排序就可以得到前 \(2^{k+1}\) 个字符的相对大小关系
代码调了一个小时才知道原来还有指针引用这种玩意
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1000010;
int t1[MAXN], t2[MAXN], sa[MAXN], tax[MAXN];
char str[MAXN];
inline void Swap(int* &a, int* &b){//丧病的复合类型
int *t = a; a = b, b = t;
}
void getSA(char s[], int len){
int p = 0, crd;
int *rak = t1, *tp = t2;
crd = 122;
for (int i = 1; i <= len; ++i) rak[i] = s[i], tp[i] = i;
for (int i = 0; i <= crd; ++i) tax[i] = 0;
for (int i = 1; i <= len; ++i) ++tax[rak[i]];
for (int i = 1; i <= crd; ++i) tax[i] += tax[i - 1];
for (int i = len; i >= 1; --i) sa[tax[rak[tp[i]]]--] = tp[i];
for (int w = 1; p != len; w <<= 1, crd = p){
p = 0;
for (int i = len - w + 1; i <= len; ++i)
tp[++p] = i;
for (int i = 1; i <= len; ++i)
if (sa[i] > w)
tp[++p] = sa[i] - w;
for (int i = 0; i <= crd; ++i) tax[i] = 0;
for (int i = 1; i <= len; ++i) ++tax[rak[i]];
for (int i = 1; i <= crd; ++i) tax[i] += tax[i - 1];
for (int i = len; i >= 1; --i) sa[tax[rak[tp[i]]]--] = tp[i];
Swap(rak, tp);
rak[sa[1]] = p = 1;
for (int i = 2; i <= len; ++i)
rak[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w]) ? p : ++p;
}
}
int main(){
scanf("%s", str + 1);
int slen = strlen(str + 1);
getSA(str, slen);
for (int i = 1; i <= slen; ++i)
printf("%d ", sa[i]);
return 0;
}
标签:后缀,tax,rak,tp,int,MAXN,笔记,数组,sa 来源: https://www.cnblogs.com/0xfffe/p/10539615.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。