字母排序
来源:互联网 发布:函数式编程 好书 编辑:程序博客网 时间:2024/06/05 02:55
转自:http://blog.csdn.net/f_zyj/article/details/75946695
问题非常简单,给定一个长度为n的字符串S,有q个操作,每次操作的形式为 i j k,表示对从i到j的这一段子串进行排序,如果k=1进行非降序排序,否则进行非升序排序。
输出最后的字符串。
样例解释:
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 5abacdabcda7 10 05 8 11 4 03 6 07 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;}
阅读全文
0 0
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母排序
- 字母字符串排序
- 一种字母排序方式
- 一种字母排序方式
- 大小字母排序
- 字母排序的实现
- 大小写字母的排序
- Poj 1318 字母排序
- 字母排序问题
- Android右侧字母排序
- Mongo查询操作
- 求解最大子数组问题
- 网易2017秋招编程题集合
- Codeforces Round #437
- tcp rto
- 字母排序
- JAVA多线程和并发基础面试问答
- localStorage 还能这么用
- JS 依然最受欢迎,GitHub 2017 开发者年度报告
- JavaScript 浮点数陷阱及解法
- ionic数据交互
- 开始Redis源码阅读
- 关于CopperCAM最新版工具v07/09/2017的破解过程
- Python学习笔记一