• CF558E


    给出一个小写字母组成的字符串,然后q个操作,a,b,c ,c为0 ,将区间 [a,b] 按逆字典序排,c为1,将此区间按字典序排。用一颗线段树,维护每个节点各个字母出现的种类数,每次操作操作后,暴力将字母a组成的区间,字母b组成的区间等等,区间内所有元素更新为a,b,等等。打个lazy标记,区间更新搞下就行了。

    #pragma comment(linker,"/STACK:102400000,102400000") 
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<iostream>
    #include<string>
    #include<queue>
    #include<stack>
    #include<list>
    #include<stdlib.h>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cstring>
    #include<set>
    using namespace std;
    typedef long long LL;
    const int mod = 1000000007;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    const int maxn = 1e5 + 20;
    int ch[maxn<<2][30];
    int color[maxn << 2];
    char str[maxn];
    void up(int rt)
    {
        for (int i = 0; i < 26; i++) {
            ch[rt][i] = ch[rt << 1][i] + ch[rt << 1 | 1][i];
        }
    }
    
    void down(int l, int r, int rt)
    {
        if (color[rt] == -1) return;
        int mid = (l + r) >> 1;
        for (int i = 0; i < 26; i++) ch[rt << 1][i] = 0, ch[rt << 1 | 1][i] = 0;
        ch[rt << 1][color[rt]] = (mid - l + 1); ch[rt << 1 | 1][color[rt]] = r - mid;
        color[rt << 1] = color[rt << 1 | 1] = color[rt];
        color[rt] = -1;
    }
    void build(int l, int r, int rt)
    {
        color[rt] = -1;
        if (l == r) {
            int t = str[l] - 'a';
            ch[rt][t]++;
            return;
        }
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        up(rt);
    }
    
    int ask(int L, int R, int add, int l, int r, int rt)
    {
        if (L <= l&&r <= R) {
            return  ch[rt][add];
        }
        int mid = (l + r) >> 1;
        int ans = 0;
        down(l, r, rt);
        if (L <= mid) ans += ask(L, R, add, lson);
        if (R > mid) ans += ask(L, R, add, rson);
        return ans;
    }
    
    
    
    void update(int L, int R, int add, int l, int r, int rt)
    {
        if (L <= l&&r <= R) {
            for (int i = 0; i < 26; i++) ch[rt][i] = 0;
            ch[rt][add] = (r - l + 1);
            color[rt] = add;
            return;
        }
        down(l, r, rt);
        int mid = (l + r) >> 1;
        if (L <= mid) update(L, R, add, lson);
        if (R > mid) update(L, R, add, rson);
        up(rt);
    }
    
    int ans = 0;
    void show(int l, int r, int rt)
    {
        if (l == r) {
            for (int i = 0; i < 26; i++) if (ch[rt][i]) printf("%c", i + 'a');
            return;
        }
        down(l,r,rt);
        int mid = (l + r) >> 1;
        show(lson); show(rson);
    }
    int cc[100];
    int main()
    {
        //freopen("1.in", "r", stdin);
        //freopen("2.in", "w", stdout);
        int q, n;
        int a, b, c;
        cin >> n >> q;
        scanf("%s", str);
        build(0, n-1, 1);
        while (q--) {
            scanf("%d%d%d", &a, &b, &c);
            a--; b--;
            if (c == 1) {
                for (int i = 0; i < 26; i++) cc[i + 1] = ask(a, b, i, 0, n - 1, 1);
                int ll = a;
                for (int i = 0; i < 26; i++) {
                    if (cc[i + 1] == 0) continue;
                    update(ll, ll + cc[i + 1] - 1, i, 0, n - 1, 1);
                    ll = ll + cc[i + 1];
                }
            }
            else {
                for (int i = 0; i < 26; i++) cc[i + 1] = ask(a, b, i, 0, n - 1, 1);
                int ll = a;
                for (int i = 25; i >= 0; i--) {
                    if (cc[i + 1] == 0) continue;
                    update(ll, ll + cc[i + 1] - 1, i, 0, n - 1, 1);
                    ll = ll + cc[i + 1];
                }
            }
        }
        show(0, n - 1, 1);
        return 0;
    }
  • 相关阅读:
    06
    05
    继承
    0713作业
    0712作业
    0711作业
    福彩双色球作业
    0709作业
    选择语句+循环语句作业
    0706作业
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4728445.html
Copyright © 2020-2023  润新知