UOJ35 后缀排序[后缀平衡树]

来源:互联网 发布:25n66aa数据 编辑:程序博客网 时间:2024/05/16 15:55

这是blog主sb时,打上的后缀平衡树版本的code

#include<cstdio>#include<cstring>#define N 200010#define LL long longint n,m,len,x,y,t,k;int ch[N][2],rd[N],cl[N],cnt,root,rank[N],sa[N],height[N];LL rk[N];int s[N];inline int randlmy(){    static int seed=142857;    return seed=int(seed*48271LL%2147483647);}void rebuild(int &rt,LL l,LL r){    if(!rt)return;    rk[rt]=l+r;    LL mid=(l+r)>>1;    rebuild(ch[rt][0],l,mid);    rebuild(ch[rt][1],mid,r);}void rotate(int &p,int d,LL l,LL r){    int q=ch[p][d^1];    ch[p][d^1]=ch[q][d];    ch[q][d]=p;    p=q;    rebuild(p,l,r);}void insert(int &rt,LL l,LL r){    LL mid=(l+r)>>1;    if(!rt){rt=cnt;rk[rt]=l+r;return;}    if(cl[cnt]<cl[rt]||(cl[cnt]==cl[rt]&&rk[cnt-1]<rk[rt-1])){insert(ch[rt][0],l,mid);if(rd[ch[rt][0]]>rd[rt])rotate(rt,1,l,r);}    else{insert(ch[rt][1],mid,r);if(rd[ch[rt][1]]>rd[rt])rotate(rt,0,l,r);}}void insert(int v){    cl[++cnt]=v;    rd[cnt]=randlmy()*randlmy();    insert(root,1,1LL<<61);}void SA(int rt){    if(!rt)return;    SA(ch[rt][0]);    sa[t]=len-rt;    rank[len-rt]=t++;    SA(ch[rt][1]);}void make_height(){    for(register int i=0;i<len;++i){          if(!rank[i]) continue;          int j=sa[rank[i]-1];          if(k)--k;        while(s[i+k]==s[j+k])++k;          height[rank[i]]=k;      }}int main(){    char ch=getchar();while(ch>'z'||ch<'a')ch=getchar();    while(ch>='a'&&ch<='z')s[len++]=ch,ch=getchar();    for(register int i=1;i<=len;++i)        insert(s[len-i]-'a');    SA(root);    make_height();    for(register int i=0;i<len;++i)        printf("%d ",sa[i]+1);printf("\n");    for(register int i=1;i<len;i++)        printf("%d ",height[i]);    return 0;}

这里写图片描述