题目大意:给一个长度为$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;
}