【tyvj1860】后缀数组

来源:互联网 发布:英语作文网络教育 编辑:程序博客网 时间:2024/06/05 18:39

传送门:http://www.tyvj.cn/p/1860

题解

后缀数组裸题,orzHZWER模板,具体的后缀数组可以参考“后缀数组处理字符串的有力工具”

还有一件最重要的事!!!这道题神卡常!!!需要输出优化!!!

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 200010using namespace std;int n,p,q,k;int a[N];int sa[2][N],rank[2][N];int h[N];int c[N];char str[N];void calsa(int *sa,int *rank,int *Sa,int *Rank){    for(int i=1;i<=n;i++)c[rank[sa[i]]]=i;    for(int i=n;i>=1;i--)if(sa[i]>k)Sa[c[rank[sa[i]-k]]--]=sa[i]-k;    for(int i=n-k+1;i<=n;i++)Sa[c[rank[i]]--]=i;    for(int i=1;i<=n;i++)        if(rank[Sa[i]]!=rank[Sa[i-1]]||rank[Sa[i]+k]!=rank[Sa[i-1]+k])            Rank[Sa[i]]=Rank[Sa[i-1]]+1;        else Rank[Sa[i]]=Rank[Sa[i-1]];}void work(){    p=0,q=1,a[0]=-1;    for(int i=1;i<=n;i++)c[a[i]]++;    for(int i=1;i<=26;i++)c[i]+=c[i-1];    for(int i=1;i<=n;i++)sa[p][c[a[i]]--]=i;    for(int i=1;i<=n;i++)        if(a[sa[p][i]]!=a[sa[p][i-1]])            rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+1;        else rank[p][sa[p][i]]=rank[p][sa[p][i-1]];    k=1;    while(k<n)    {        calsa(sa[p],rank[p],sa[q],rank[q]);        p^=1,q^=1,k<<=1;    }}void getans(){    k=0;    for(int i=1;i<=n;i++)    {        if(rank[p][i]==1)h[rank[p][i]]=0;        else{            if(k)k--;            int j=sa[p][rank[p][i]-1];            while(a[i+k]==a[j+k])k++;            h[rank[p][i]]=k;        }    }}void putt(int x){    if(!x)return ;    char c=x%10+'0';    putt(x/10);    putchar(c);}int main(){    scanf("%s",str+1);    n=strlen(str+1);    for(int i=1;i<=n;i++)a[i]=str[i]-'a'+1;    work();    getans();    for(int i=1;i<=n;i++)        putt(sa[p][i]),putchar(' ');    puts("");    for(int i=1;i<=n;i++)    {        if(h[i])putt(h[i]);        else putchar('0');        putchar(' ');    }    puts("");    return 0;}
0 0
原创粉丝点击