字母排序

来源:互联网 发布:函数式编程 好书 编辑:程序博客网 时间: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;}