首页 > 其他分享 >洛谷P4051 [JSOI2007]字符加密 题解 后缀数组sa的应用

洛谷P4051 [JSOI2007]字符加密 题解 后缀数组sa的应用

时间:2023-03-02 12:56:40浏览次数:47  
标签:字符 洛谷 题解 maxn 数组 P4051 字符串 sa

题目链接:https://www.luogu.com.cn/problem/P4051

题目大意:

给定一个长度为 \(n\) 的字符串 \(s\),每次将 \(s\) 的首字符取出放到末尾……

这样能得到 \(n\) 个字符串。

将这 \(n\) 个字符串按字典序排序,然后输出每个字符串末尾的字符。

解题思路:

将字符串 \(s\) 翻倍(\(s \rightarrow ss\)),然后求 \(sa\) 数组,然后按 \(sa[i]\) 从小到大输出合法的子串(因为大小增加了一倍,后一半的都是不合法的子串,忽略即可)。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, w, sa[maxn], rk[maxn], oldrk[maxn<<1];
char s[maxn];

int main() {
    scanf("%s", s+1);
    n = strlen(s+1);
    strncpy(s+1+n, s+1, sizeof(char)*n);
    n <<= 1;

    for (int i = 1; i <= n; i++) sa[i] = i, rk[i] = s[i];

    for (w = 1; w < n; w <<= 1) {
        sort(sa+1, sa+n+1, [](int i, int j) {
            return rk[i] == rk[j] ? rk[i + w] < rk[j + w] : rk[i] < rk[j];
        });
        memcpy(oldrk, rk, sizeof(int)*(n+1));
        for (int i = 1, p = 0; i <= n; i++) {
            if (oldrk[sa[i]] != oldrk[sa[i-1]] || oldrk[sa[i] + w] != oldrk[sa[i-1] + w])
                p++;
            rk[sa[i]] = p;
        }
    }

    for (int i = 1; i <= n; i++)
        if (sa[i] <= n/2)
            putchar(s[sa[i] + n/2 - 1]);

    return 0;
}

标签:字符,洛谷,题解,maxn,数组,P4051,字符串,sa
From: https://www.cnblogs.com/quanjun/p/17171407.html

相关文章

  • iframe sanbox 造成附件下载问题解决
    问题场景,iframe通过src加载三方website,同时三方website调用api生成web页面,页面中会包含click链接(打开新页面)之后会包含文件下载参考图如下  问题对于通过a......
  • VUE前端请求跨域问题解决
    解决方法:vue.config.js文件配置:module.exports={devServer:{open:true,host:'192.168.1.193',port:8080,https:fals......
  • Failed to run MSBuild command 错误问题解决
    场景:提示:这里简述项目相关背景:CMake报错CMakeERRORFailedtorunMSBuildcommand:MSBuild.exe。如下图所示: 问题描述提示:这里描述项目中遇到的问题:①cmake报错......
  • LOJ 3276 JOISC 2020 Day2 遗迹 题解 (计数DP)
    LOJ链接UOJ链接观察一下n次地震的过程,发现最后会有n个石柱高度为0,\(1,2\cdotsn\)高度的石柱各有一个。假设现在已经确定了一种初始高度状态,我们来看看最后哪些石柱高度......
  • P8631 [蓝桥杯 2015 国 AC] 切开字符串 题解
    P8631[蓝桥杯2015国AC]切开字符串题解前言看到这题没有人写题解,就打算写一篇。这也是蒟蒻的第一篇题解。前置知识\(manacher\),\(SA\)。如果不会可以转至mana......
  • ABC275D-Yet-Another-Recursive-Function题解
    题目传送门题意:定义一个\(\mathbb{N}\to\mathbb{N}\)的函数\(f(x)=\begin{cases}1&x=0\\f(\lfloor\frac{x}{2}\rfloor)+f(\lfloor\frac{x}{3}\rfloor)&\text{otherwis......
  • CF71D-Solitaire题解
    题目传送门题意:一副扑克牌由54张牌组成,包括52张基本牌和两张“王”。在本题中每张牌用两个字符表示:对于基本牌,第一个字符为点数,有'2''3''4''5''6''7''8''9......
  • CF118C-Fancy-Number题解
    题目传送门题意:有一个\(n\)位的数字串,每位为\(0-9\)。每次操作可以更改一位的数字,代价为新旧两位数字之差。问使字符串存在某一个数的出现次数超过\(k\)的最小代价......
  • CF15D-Map题解
    题目传送门题意:有一个\(n\timesm\)的矩阵,每个格子有一个权值。每次操作会选择一个\(x\timesy\)的矩形区域,花费为“每个位置的权值减去最小权值”之和,区域之间不能......
  • CF杂题题解
    129B.StudentsandShoelaces题意:一个\(n\)个点\(m\)条边的无向图,每一轮删去所有度数为\(1\)的点,问删几轮停止。暴力模拟每一轮即可,每次删点更新邻居度数。{%......