bzoj1031 [JSOI2007]字符加密 后缀数组改

来源:互联网 发布:成都富士康java 编辑:程序博客网 时间:2024/06/08 05:17

DA后缀数组构造的思想主要的就是倍增

即类似RMQ的双关键字排序

所以就可以用双关键字排序的方法来构造后缀数组

基数排序和快排都可以,鉴于是1e5,直接nlogn就够了


码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 500005int rk[N],len,n,i,k,cnt;char str[N];struct SA{int x,y,id;}sa[N];bool cmp(SA a,SA b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}void Da2(){for(i=0;i<n;i++)sa[i].x=str[i],sa[i].id=i;for(k=1;k<n;k*=2){for(i=0;i<n;i++)sa[i].y=sa[i+k].x;//得到第二关键字sort(sa,sa+n,cmp);//排序 cnt=0;for(i=0;i<n;i++){if(sa[i].x==sa[i-1].x&&sa[i].y==sa[i-1].y);else cnt++;rk[sa[i].id]=cnt;    }for(i=0;i<n;i++)sa[i].x=rk[i],sa[i].id=i;}}int main(){scanf("%s",str);len=strlen(str);for(i=len;i<len*2-1;i++)str[i]=str[i-len];n=len*2-1;Da2();sort(sa,sa+n,cmp);for(i=0;i<n;i++){if(sa[i].id<len)printf("%c",str[sa[i].id+len-1]);}}


阅读全文
0 0
原创粉丝点击