转自:http://blog.csdn.net/f_zyj/article/details/75946695
问题非常简单,给定一个长度为n的字符串S,有q个操作,每次操作的形式为 i j k,表示对从i到j的这一段子串进行排序,如果k=1进行非降序排序,否则进行非升序排序。
输出最后的字符串。
样例解释:
![](https://img.51nod.com/upload/000FBEF4/08D2914F6D9EE2950000000000000012.png)
Input
单组测试数据。 第一行有两个整数n, q (1 ≤ n ≤ 10^5, 0 ≤ q ≤ 50 000),表示字符串的长度和操作次数。 第二行有一个字符串。只由小写字母组成。 接下来q行,每行包含三个整数 i,j,k(1 ≤ i ≤ j ≤ n, k∈{0,1})。
Output
输出最后的字符串。
Input示例
10 5 abacdabcda 7 10 0 5 8 1 1 4 0 3 6 0 7 10 1
Output示例
cbcaaaabdd
#include <cstdio> #include <vector> #include <iostream> #include <set> using namespace std; const int MAXN = 1e5 + 10; const int MAXK = 26; int n, q; bool vis[MAXN]; char s[MAXN]; char ans[MAXN]; int cnt[MAXN][MAXK]; // cnt[i][j] 以 i 开头的后边紧跟着的有序序列每种字母的个数 set<int> si; void split(int p) { int l, len; set<int>::iterator it = si.lower_bound(p); if (*it == p) { return ; } len = *it; l = *(--it); len -= l; vis[p] = vis[l]; if (!vis[l]) { for (int i = 0; i < MAXK; i++) { if (len - cnt[l][i] > p - l) { cnt[p][i] += cnt[l][i]; len -= cnt[l][i]; cnt[l][i] = 0; } else { int num = len - (p - l); cnt[p][i] += num; cnt[l][i] -= num; break; } } } else { for (int i = MAXK - 1; i >= 0; i--) { if (len - cnt[l][i] > p - l) { cnt[p][i] += cnt[l][i]; len -= cnt[l][i]; cnt[l][i] = 0; } else { int num = len - (p - l); cnt[p][i] += num; cnt[l][i] -= num; break; } } } si.insert(p); } void merge(int l, int r, int k) { vis[l] = k; vector<int> v; set<int>::iterator end = si.find(r); set<int>::iterator sta = si.find(l); for (sta++; sta != end; sta++) { for (int i = 0; i < MAXK; i++) { cnt[l][i] += cnt[*sta][i]; cnt[*sta][i] = 0; } v.push_back(*sta); } for (int i = 0; i < v.size(); i++) { si.erase(v[i]); } } template <class T> inline void scan_d(T &ret) { char c; ret = 0; while ((c = getchar()) < '0' || c > '9'); while (c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'), c = getchar(); } } int main() { scan_d(n), scan_d(q); scanf("%s", s + 1); for (int i = 1; i <= n; i++) { cnt[i][s[i] - 'a']++; si.insert(i); vis[i] = 1; } si.insert(n + 1); int l, r, k; while (q--) { scan_d(l), scan_d(r), scan_d(k); split(l), split(r + 1); merge(l, r + 1, k); } int pos = 1; for (set<int>::iterator it = si.begin(); it != si.end(); it++) { if (vis[*it]) { for (int i = 0; i < MAXK; i++) { for (int j = 0; j < cnt[*it][i]; j++) { ans[pos++] = 'a' + i; } } } else { for (int i = MAXK - 1; i >= 0; i--) { for (int j = 0; j < cnt[*it][i]; j++) { ans[pos++] = 'a' + i; } } } } puts(ans + 1); return 0; }