zoukankan      html  css  js  c++  java
  • 【BZOJ 1031】[JSOI2007]字符加密Cipher(后缀数组模板)

    【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1031

    【题意】

    【题解】

    后缀数组模板题;
    把整个字符串扩大一倍.
    即长度乘2
    然后搞出后缀数组;
    然后顺序枚举i;
    对于sa[i]< n的输出对应的s[sa[i]+n-1]就好了
    后缀的含义是把后缀按照字典序从小到大排一下.
    按照这个规则;
    就能搞了;
    必然是在前n个字符中就能比较出来;
    所以及时后缀多了一些也没事.

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int, int> pii;
    typedef pair<LL, LL> pll;
    
    const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
    const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
    const double pi = acos(-1.0);
    const int N = 1e5+100;
    
    char s[N * 2];
    int sa[N * 2], wv[2][350005], tong[N * 2];
    
    bool cmp(int *tmp, int x, int y, int j)
    {
        return tmp[x] == tmp[y] && tmp[x + j] == tmp[y + j];
    }
    
    void getsa(int n, int m)
    {
        int p = 0, *x = wv[0], *y = wv[1];
        rep1(i, 0, n - 1)
            ++tong[x[i] = s[i]];
        rep1(i, 1, m - 1)
            tong[i] += tong[i - 1];
        rep2(i, n - 1, 0)
            sa[--tong[x[i]]] = i;
        for (int j = 1; p != n; j <<= 1, m = p)
        {
            p = 0;
            rep1(i,n-j,n-1)
                y[p++] = i;
            rep1(i, 0, n - 1)
                if (sa[i] >= j)
                    y[p++] = sa[i] - j;
            rep1(i, 0, m - 1)
                tong[i] = 0;
            rep1(i, 0, n - 1)
                ++tong[x[y[i]]];
            rep1(i, 1, m - 1)
                tong[i] += tong[i - 1];
            rep2(i, n - 1, 0)
                sa[--tong[x[y[i]]]] = y[i];
            swap(x, y), p = 1, x[sa[0]] = 0;
            rep1(i, 1, n - 1)
                x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;
        }
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        int n;
        scanf("%s", s);
        n = strlen(s);
        rep1(i, 0, n - 1)
            s[i + n] = s[i];
        getsa(n << 1 | 1, 128);
        rep1(i, 1, n << 1)
            if (sa[i] < n)
                putchar(s[sa[i] + n - 1]);
        puts("");
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
    
  • 相关阅读:
    yum 下载安装包以及依赖包
    《将博客搬至CSDN》
    Lucene
    Solr
    LVS原理详解(3种工作模式及8种调度算法)
    正向代理与反向代理
    网关,网卡
    NAT地址转换
    Nginx学习总结
    网络_OSI模型_数据包传输
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626540.html
Copyright © 2011-2022 走看看