[洛谷P5329][SNOI2019]字符串

题目大意:给一个长度为$n$的字符串$s$,字符串$p_i$为字符串$s$去掉第$i$个字符后形成的字符串。请给所有字符串$p_i$排序(相同字符串按编号排序)

题解:先去掉所有连续相同字符,因为它们形成的字符串一定相同(也就是说只按编号排序)。然后发现对于两个字符串$p_i,p_j(i<j)$只需要比较$s_i$与$s_{i+1}$的大小就可以比较这两个字符串的大小。即$p_i$只会排在$p_{i+1}\sim p_n$的前面或后面。所以可以用链表解决

卡点:

 

C++ Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 1000010

int n, m;
int pos[maxn], len[maxn], nxt[maxn];
char s[maxn], p[maxn];
int main() {
    std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    std::cin >> n >> (s + 1);
    for (int i = 1, j = i; i <= n; i = j) {
        while (j <= n && s[i] == s[j]) ++j;
        p[++m] = s[i], pos[m] = i, len[m] = j - i;
    }
    int L, R; L = R = m;
    for (int i = m - 1; i; --i)
        if (p[i] > p[i + 1]) nxt[i] = L, L = i;
        else nxt[R] = i, R = i;
    for (int i = L; i; i = nxt[i])
        for (int j = 0; j < len[i]; ++j) std::cout << pos[i] + j << ' ';
    return 0;
}

 

posted @ 2019-07-02 17:26  Memory_of_winter  阅读(154)  评论(0编辑  收藏  举报