P3809 模板后缀排序
Posted fighting-sh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3809 模板后缀排序相关的知识,希望对你有一定的参考价值。
P3809 【模板】后缀排序
https://www.luogu.org/problemnew/show/P3809
题目背景
这是一道模板题。
题目描述
读入一个长度为 nn 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 11 到 nn。
输入输出格式
输入格式:
一行一个长度为 nn 的仅包含大小写英文字母或数字的字符串。
输出格式:
一行,共n个整数,表示答案。
输入输出样例
说明
n <= 10^6
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define maxn 1000006 5 6 struct DA{ 7 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 8 int cmp(int *r,int a,int b,int l){ 9 return r[a]==r[b]&&r[a+l]==r[b+l]; 10 } 11 12 void da(int *r,int *sa,int n,int m){ 13 int i,j,p,*x=wa,*y=wb,*t; 14 for(i=0;i<m;i++) ws[i]=0; 15 for(i=0;i<n;i++) ws[x[i]=r[i]]++; 16 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 17 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 18 for(j=1,p=1;p<n;j*=2,m=p){ 19 for(p=0,i=n-j;i<n;i++) y[p++]=i; 20 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 21 for(i=0;i<n;i++) wv[i]=x[y[i]]; 22 for(i=0;i<m;i++) ws[i]=0; 23 for(i=0;i<n;i++) ws[wv[i]]++; 24 for(i=1;i<m;i++) ws[i]+=ws[i-1]; 25 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; 26 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 27 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 28 } 29 return; 30 } 31 }da; 32 33 int a[maxn],b[maxn]; 34 char str[maxn]; 35 36 int main(){ 37 #ifndef ONLINE_JUDGE 38 // freopen("input.txt","r",stdin); 39 #endif 40 std::ios::sync_with_stdio(false); 41 cin>>(str); 42 int len=strlen(str); 43 for(int i=0;i<len;i++) a[i]=str[i]; 44 da.da(a,b,len+1,255); 45 for(int i=1;i<=len;i++) cout<<b[i]+1<<" "; 46 cout<<endl; 47 }
以上是关于P3809 模板后缀排序的主要内容,如果未能解决你的问题,请参考以下文章