[洛谷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; }