• CodeForces 588E A Simple Task(线段树)


    This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

    Output the final string after applying the queries.

    Input
    The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively.

    Next line contains a string S itself. It contains only lowercase English letters.

    Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, ).

    Output
    Output one line, the string S after applying the queries.

    Examples
    Input
    10 5
    abacdabcda
    7 10 0
    5 8 1
    1 4 0
    3 6 0
    7 10 1
    Output
    cbcaaaabdd
    Input
    10 1
    agjucbvdfk
    1 10 1
    Output
    abcdfgjkuv
    Note
    First sample test explanation:

     

    题意:

    给出一个字符串,两种操作,操作0,将l-r区间降序排序,操作1,将l-r区间升序排序。

    输出经过所有操作后的字符串

    题解:

    建26棵线段树,区间查询个数,点修改,对于每个操作,升序从1-26计数排序,降序从26-1计数排序

    最后单点查询

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lson root<<1
    #define rson root<<1|1
    using namespace std;
    
    struct oper
    {
        int l,r;
    } op[26];
    
    struct seg_tree
    {
        struct node
        {
            int l,r,lazy,sum;
        } tr[400010];
    
        void push_up(int root)
        {
            tr[root].sum=tr[lson].sum+tr[rson].sum;
        }
    
        void push_down(int root)
        {
            int mid=(tr[root].l+tr[root].r)>>1;
            tr[lson].sum=(mid-tr[root].l+1)*tr[root].lazy;
            tr[lson].lazy=tr[root].lazy;
            tr[rson].sum=(tr[root].r-mid)*tr[root].lazy;
            tr[rson].lazy=tr[root].lazy;
            tr[root].lazy=-1;
        }
    
        void build(int root,int l,int r)
        {
            if(l==r)
            {
                tr[root].l=l;
                tr[root].r=r;
                tr[root].lazy=-1;
                return ;
            }
    
            int mid=(l+r)>>1;
            tr[root].l=l;
            tr[root].r=r;
            tr[root].lazy=-1;
            build(lson,l,mid);
            build(rson,mid+1,r);
        }
    
        void update(int root,int l,int r,int val)
        {
            if(l>r)
            {
                return ;
            }
            if(tr[root].l==l&&tr[root].r==r)
            {
                tr[root].sum=(tr[root].r-tr[root].l+1)*val;
                tr[root].lazy=val;
                return ;
            }
            if(~tr[root].lazy)
            {
                push_down(root);
            }
            int mid=(tr[root].l+tr[root].r)>>1;
            if(l>mid)
            {
                update(rson,l,r,val);
            }
            else
            {
                if(mid>=r)
                {
                    update(lson,l,r,val);
                }
                else
                {
                    update(lson,l,mid,val);
                    update(rson,mid+1,r,val);
                }
            }
            push_up(root);
        }
    
        int query(int root,int l,int r)
        {
            if(tr[root].l==l&&tr[root].r==r)
            {
                return tr[root].sum;
            }
            if(~tr[root].lazy)
            {
                push_down(root);
            }
            int mid=(tr[root].l+tr[root].r)>>1;
            if(l>mid)
            {
                return query(rson,l,r);
            }
            else
            {
                if(mid>=r)
                {
                    return query(lson,l,r);
                }
                else
                {
                    return query(lson,l,mid)+query(rson,mid+1,r);
                }
            }
        }
    
    } tree[26];
    
    char c[100010];
    
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        scanf("%s",c+1);
        for(register int i=0; i<26; ++i)
        {
            tree[i].build(1,1,n);
        }
        for(register int i=1; i<=n; ++i)
        {
            tree[c[i]-'a'].update(1,i,i,1);
        }
        int l,r,kd,he,ta;
        for(; m--;)
        {
            scanf("%d%d%d",&l,&r,&kd);
            ta=l-1;
            if(kd)
            {
                for(register int i=0; i<26; ++i)
                {
                    he=ta+1;
                    ta=he+tree[i].query(1,l,r)-1;
                    op[i].l=he;
                    op[i].r=ta;
                }
            }
            else
            {
                for(register  int i=25; i>=0; --i)
                {
                    he=ta+1;
                    ta=he+tree[i].query(1,l,r)-1;
                    op[i].l=he;
                    op[i].r=ta;
                }
            }
            for(register int i=0; i<26; ++i)
            {
                if(op[i].l<=op[i].r)
                {
                    tree[i].update(1,op[i].l,op[i].r,1);
                    tree[i].update(1,l,op[i].l-1,0);
                    tree[i].update(1,op[i].r+1,r,0);
                }
            }
        }
    
        for(register int i=1; i<=n; ++i)
        {
            for(register int j=0; j<26; ++j)
            {
                if(tree[j].query(1,i,i))
                {
                    putchar(j+97);
                    break;
                }
            }
        }
    }

     

     

     

     

  • 相关阅读:
    [转]进程与线程及其区别
    [转]工厂模式
    [转]Filter实现处理中文乱码,转义html标签,过滤敏感词
    [转]JAVA设计模式之单例模式
    [转]Servlet 中文乱码问题及解决方案剖析
    Servlet作业2-将表单提交的商品信息输出到页面中
    Servlet作业1-实现注册登录
    [转] ServletContext 与application的异同
    [转]servlet中的service, doGet, doPost方法的区别和联系
    [转]Servlet 3.0 新特性详解
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/9019727.html
Copyright © 2020-2023  润新知