Luogu4051 / BZOJ1031 [JSOI2007] suffix array of characters encrypted

Topic Portal

Analysis of Algorithms

This problem is equivalent to the ring string suffix sorting, general policy processing loop on the issue is 破环为链, then doubled the original string copied back the original string, then this new string suffix sorting.

Why is this algorithm is correct? Suffix \ (> n \) that part of the string will not affect the answer?

Because we only focus on the first new string suffix \ (n \) position, and only two suffixes meet before \ (n \) bits are identical will be compared later time, this situation will only shaped like aaaaathis string appears, it is clear that no matter what string sort order will not affect the results.

Note 2 times the open space! ! !

Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005//错误笔记:复制二倍数组没开够 
#define maxm 400005
char s[maxn];
int n;
int sa[2][maxn],rk[2][maxn],v[maxn];
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;i++)s[i+n]=s[i];
    n=strlen(s+1);
    int p=0,q=1;
    for(int i=1;i<=n;i++)v[s[i]]++;
    for(int i=1;i<128;i++)v[i]+=v[i-1];
    for(int i=1;i<=n;i++)sa[0][v[s[i]]--]=i;
    for(int i=1;i<=n;i++)rk[0][sa[0][i]]=rk[0][sa[0][i-1]]+(s[sa[0][i-1]]!=s[sa[0][i]]);
    for(int k=1;k<=n;(k<<=1),swap(p,q)){
        for(int i=1;i<=n;i++)v[rk[p][sa[p][i]]]=i;
        for(int i=n;i;i--)
            if(sa[p][i]>k)sa[q][v[rk[p][sa[p][i]-k]]--]=sa[p][i]-k;
        for(int i=n-k+1;i<=n;i++)sa[q][v[rk[p][i]]--]=i;
        for(int i=1;i<=n;i++)rk[q][sa[q][i]]=rk[q][sa[q][i-1]]+((rk[p][sa[q][i]]!=rk[p][sa[q][i-1]])||(rk[p][sa[q][i]+k]!=rk[p][sa[q][i-1]+k]));
        if(rk[q][sa[q][n]]==n)break;
    }
    for(int i=1;i<=n;i++)
        if(sa[q][i]<=n/2)printf("%c",s[sa[q][i]+n/2-1]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/ZigZagKmp/p/11479796.html