• [BZOJ1031][JSOI2007]字符加密Cipher


    1031: [JSOI2007]字符加密Cipher

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7384  Solved: 3198 [Submit][Status][Discuss]

    Description

      喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法
    :把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:

     

    JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07
     OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是
    突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?

    Input

      输入文件包含一行,欲加密的字符串。注意字符串的内容不一定是字母、数字,也可以是符号等。

    Output

      输出一行,为加密后的字符串。

    Sample Input

    JSOI07

    Sample Output

    I0O7SJ

    HINT

    对于100%的数据字符串的长度不超过100000。

    把原串$S$复制一遍放在后面变为$SS$,求出$SS$的后缀数组,然后按序输出即可

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 200000 + 10;
    int sa[maxn], rank[maxn], tp[maxn], tax[maxn];
    int n, m;
    char s[maxn];
    inline void Rsort(){
        for(int i = 0; i <= m; i++) tax[i] = 0;
        for(int i = 1; i <= n; i++) tax[rank[tp[i]]]++;
        for(int i = 1; i <= m; i++) tax[i] += tax[i - 1];
        for(int i = n; i; i--) sa[tax[rank[tp[i]]]--] = tp[i];
    }
    bool inline cmp(int *a, int l, int r, int w){
        return a[l] == a[r] && a[l + w] == a[r + w]; 
    }
    void suffix(){
        m = 127;
        for(int i = 1; i <= n; i++){
            rank[i] = s[i];
            tp[i] = i;
        }
        Rsort();
        for(int p, w = 1; p < n; w <<= 1, m = p){
            p = 0;
            for(int i = n - w + 1; i <= n; i++) tp[++p] = i;
            for(int i = 1; i <= n; i++)
                if(sa[i] > w) tp[++p] = sa[i] - w;
            Rsort();
            swap(rank, tp);
            p = rank[sa[1]] = 1;
            for(int i = 2; i <= n; i++)
                rank[sa[i]] = cmp(tp, sa[i], sa[i - 1], w) ? p : ++p;
        }
    }
    int main(){
        scanf("%s", s + 1);
        n = strlen(s + 1);
        for(int i = 1; i <= n; i++)
            s[i + n] = s[i];
        n <<= 1;
        suffix();
        n >>= 1;
        for(int i = 1; i <= (n << 1); i++)
            if(sa[i] <= n) printf("%c", s[sa[i] + n - 1]);
        return 0;
    }
  • 相关阅读:
    为什么你不会redis分布式锁?因为你没看到这篇文章
    JavaScript最佳做法—创建对象
    js构造函数的定义
    作用域和闭包
    js中的call()和apply()的区别
    3种方法快速查找两个数组是否在Javascript中包含任何公共项
    JavaScript继承的6种方式以及它们的优缺点
    JS常见的内存泄漏及可用的解决方法
    Vuex简单入门
    如何使用HTML和CSS为背景创建Wave图片?
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7440324.html
Copyright © 2020-2023  润新知