• (后缀数组模板)BZOJ1031[JSOI2007]字符加密Cipher


    BZOJ1031-[JSOI2007]字符加密Cipher

      题意:

        

      题解:

        这道题约等于后缀数组的模板题了.把字符串复制一份接在原字符串的尾部,形成一个新字符串.对这个字符串进行后缀排序,前一半的排名就是按题意排序后的结果.

        第一次写后缀数组,有很多细节要注意,也调了好久,代码里面基本上是一行一个for循环,差点被搞炸.

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=400000;
    char s[N+10];
    int n,ch_sz=200,sa[N+10],rk[N+10],c[N+10],sa2[N+10],p;
    void sort_suffix(){
        for(int i=1;i<=n;++i) ++c[rk[i]=s[i]];
        for(int i=1;i<=ch_sz;++i) c[i]+=c[i-1];
        for(int i=n;i>=1;--i) sa[c[rk[i]]--]=i;
        for(int i=1;i<=n;i*=2){
            p=0;
            for(int j=n-i+1;j<=n;++j) sa2[++p]=j;
            for(int j=1;j<=n;++j) if(sa[j]>i) sa2[++p]=sa[j]-i;
            for(int j=1;j<=ch_sz;++j) c[j]=0;
            for(int j=1;j<=n;++j) ++c[rk[sa2[j]]];
            for(int j=1;j<=ch_sz;++j) c[j]+=c[j-1];
            for(int j=n;j>=1;--j) sa[c[rk[sa2[j]]]--]=sa2[j];
            swap(rk,sa2); rk[sa[1]]=ch_sz=1;
            for(int j=2;j<=n;++j)
                rk[sa[j]]=sa2[sa[j]]==sa2[sa[j-1]]&&sa2[sa[j]+i]==sa2[sa[j-1]+i]?ch_sz:++ch_sz;
            if(ch_sz==n) break;
        }
    }
    int main(){
        scanf("%s",s+1); n=strlen(s+1);
        for(int i=n+1;i<=n*2;++i) s[i]=s[i-n];
        n<<=1;
        sort_suffix();
        for(int i=1;i<=n;++i) if(sa[i]<=n/2) printf("%c",s[sa[i]+n/2-1]);
        return 0;
    }
  • 相关阅读:
    mysql 开发基础系列7 流程函数与其它函数
    mysql 开发基础系列6 数值与日期函数
    html5 浏览器端数据库
    html5 响应式布局
    css 文本溢出显示省略号
    js 字符串的操作
    js 图片轮播(一)
    css 弹出层-透明层
    js选项卡
    js获取当前时间显示在页面上
  • 原文地址:https://www.cnblogs.com/jxcakak/p/7570994.html
Copyright © 2020-2023  润新知