BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组

来源:互联网 发布:围棋打谱 mac 编辑:程序博客网 时间:2024/05/17 04:49

一道后缀数组模板题,拿来练练后缀数组(Po姐的模板强无敌),将字符串复制一遍然后求一下后缀数组将所有编号小于等于n的提出来就好啦

#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>#include<iomanip>#include<algorithm>#include<ctime>#include<string>using namespace std;int sa[1000000];int rank[1000000];int x[1000000];int y[1000000];int temp[1000000];int sum[1000000];char s[1000000];int len;int tot;void get_rank(){    for(int i=1;i<=len;i++) sum[s[i]]++;    for(int i=1;i<=127;i++) sum[i]+=sum[i-1];    for(int i=len;i>=1;i--) temp[sum[s[i]]--]=i;    tot=0;    for(int i=1;i<=len;i++)    {        if(i==1 || s[temp[i]]!=s[temp[i-1]]) tot++;        rank[temp[i]]=tot;    }}void ji_sort(int key[],int order[]){    for(int i=0;i<=len;i++) sum[i]=0;    for(int i=1;i<=len;i++) sum[key[order[i]]]++;    for(int i=1;i<=len;i++) sum[i]+=sum[i-1];    for(int i=len;i>=1;i--) temp[sum[key[order[i]]]--]=order[i];    tot=0;    for(int i=1;i<=len;i++) order[i]=temp[i];}void get_hou(){    get_rank();    for(int j=1;j<=len;j<<=1)    {        for(int i=1;i<=len;i++)        {            x[i]=rank[i];            y[i]=i+j>len? 0 :rank[i+j];            sa[i]=i;        }        ji_sort(y,sa);        ji_sort(x,sa);        tot=0;        for(int i=1;i<=len;i++)        {            if(i==1 || x[sa[i]]!=x[sa[i-1]] || y[sa[i]]!=y[sa[i-1]]) tot++;            rank[sa[i]]=tot;        }    }}int main(){    scanf("%s",s+1);    len=strlen(s+1);    for(int i=1;i<=len;i++) s[len+i]=s[i];    s[len+len+1]=s[1];    int yuanlen=len;    len=len*2+1;    get_hou();    for(int i=1;i<=len;i++)    {        if(sa[i]<=yuanlen) printf("%c",s[sa[i]+yuanlen-1]);    }    return 0;}
0 1
原创粉丝点击