[template] suffix array (Luogu P3809)
The template title of Luogu
Template code is everywhere
The template has various detailed comments everywhere
I just can't understand
They said that to understand code, we need to learn cardinality sorting first. I'll learn it, and then I can understand it
Come back to understand suffix array or not
Listen to all kinds of people tell me the same feeling every time. It seems that they understand each other. Suddenly they don't
I know that LCA and I finally understood this in voice yesterday morning
Finally, we find that the problem is still in cardinal ordering
Radix sorting
It's a stable sort, which I've been struggling with for two months
Stable sorting is based on the original arrangement
In other words, when two elements of the same size are encountered, they should be sorted according to the size of their last round
This ensures that the second keyword does not need to be taken out separately and rearranged when sorting the suffix array
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10000010
int c[300];
int t1[maxn],t2[maxn];
char str[maxn];
int sa[maxn];
void SA(int n){
int *x=t1,*y=t2,m=127;
for(int i=1;i<=m;++i) c[i]=0;
for(int i=1;i<=n;++i) c[x[i]=str[i]]++;
for(int i=1;i<=m;++i) c[i]+=c[i-1];
for(int i=n;i;--i) sa[c[x[i]]--]=i;
for(int k=1;k<=n;k<<=1){
int p=0;
for(int i=n-k+1;i<=n;++i) y[++p]=i;
for(int i=1;i<=n;++i) if(sa[i]>k) y[++p]=sa[i]-k;
for(int i=1;i<=m;++i) c[i]=0;
for(int i=1;i<=n;++i) c[x[y[i]]]++;
for(int i=1;i<=m;++i) c[i]+=c[i-1];
for(int i=n;i;--i) sa[c[x[y[i]]]--]=y[i];
/*
The problem is basically in the above three lines. It is also the cardinality sorting before the multiplication
Basically, the only difference between the two paragraphs is that I and y[i]
I haven't found this detail before. Today I realized it
i before multiplication is not arranged in the original sequence, and it should be arranged according to the original position
Now, y[i] is the result of the last row. It moves k bits to the left, which is the second keyword
The point is that if the cardinality sorting is equal, the original order of the second key will not be damaged
*/
swap(x,y);
x[sa[1]]=1,p=1;
for(int i=2;i<=n;++i){
x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p:++p;
}
m=p;
if(p>=n) break;
}
}
int main(){
scanf("%s",str+1);
int len=strlen(str+1);
SA(len);
for(int i=1;i<=len;++i){
printf("%d ",sa[i]);
}
return 0;
}