• BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题


    BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题

    将字符串复制一遍接在原串后面,然后后缀排序即可。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define space putchar(' ')
    #define enter putchar('
    ')
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c > '9' || c < '0')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x){
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    const int N = 400005;
    int n, buf1[N], buf2[N], sa[N], buc[N], rnk[N];
    char s[N];
    
    void suffix_sort(){
        int *x = buf1, *y = buf2, m = 127;
        for(int i = 0; i <= m; i++) buc[i] = 0;
        for(int i = 1; i <= n; i++) buc[x[i] = s[i]]++;
        for(int i = 1; i <= m; i++) buc[i] += buc[i - 1];
        for(int i = n; i; i--) sa[buc[x[i]]--] = i;
        for(int k = 1, p = 0; k <= n; k <<= 1, m = p, p = 0){
            for(int i = n - k + 1; i <= n; i++) y[++p] = i;
            for(int i = 1; i <= n; i++) if(sa[i] > k) y[++p] = sa[i] - k;
            for(int i = 0; i <= m; i++) buc[i] = 0;
            for(int i = 1; i <= n; i++) buc[x[y[i]]]++;
            for(int i = 1; i <= m; i++) buc[i] += buc[i - 1];
            for(int i = n; i; i--) sa[buc[x[y[i]]]--] = y[i];
            swap(x, y), x[sa[1]] = p = 1;
            for(int i = 2; i <= n; i++)
                if(y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) x[sa[i]] = p;
                else x[sa[i]] = ++p;
            if(p >= n) break;
        }
        for(int i = 1; i <= n; i++) rnk[sa[i]] = i;
    }
    
    int main(){
    
        scanf("%s", s + 1), n = strlen(s + 1);
        for(int i = 1; i <= n; i++) s[n + i] = s[i];
        n *= 2;
        suffix_sort();
        n /= 2;
        for(int i = 1; i <= 2 * n; i++)
            if(sa[i] <= n) putchar(s[sa[i] + n - 1]);
        enter;
        
        return 0;
    }
    
  • 相关阅读:
    Luogu P2016 战略游戏(树形DP)
    Luogu P2486 染色(树链剖分+线段树)
    Luogu P3178 树上操作(树链剖分+线段树)
    Luogu P2590 树的统计(树链剖分+线段树)
    Luogu P2146 软件包管理器(树链剖分+线段树)
    获得spring
    网卡绑定多个ip
    描述01-配置文件咋整
    进程查看
    端口查看,进程杀死
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/BZOJ1031.html
Copyright © 2020-2023  润新知