• 考试题string——线段树。


    string
    【题目描述】
    给定一个由小写字母组成的字符串 s。有 m 次操作,每次操作给
    定 3 个参数 l,r,x。如果 x=1,将 s[l]~s[r]升序排序;如果 x=0,将 s[l]~s[r]
    降序排序。你需要求出最终序列。
    【输入数据】
    第一行两个整数 n,m。第二行一个字符串 s。接下来 m 行每行三
    个整数 x,l,r。
    【输出数据】
    一行一个字符串表示答案。
    【样例输入】
    5 2
    cabcd
    1 3 1
    3 5 0
    【样例输出】
    abdcc
    【数据范围】
    对于 40%的数据,n,m<=1000。
    对于 100%的数据,n,m<=100000。

    题解:

      正解不明,但可以写出nlogn*26*26的线段树(然而只比暴力多10分)。

      看到一共只有26个字母,考虑枚举每个字母,统计在区间内部的个数,那么对于每种字母,显然如果按顺序排序,那么显然是从a~z,一个一个区间覆盖,区间清空。

      线段树实现,当然lz打的是区间覆盖的标记,只要当前这个节点的元素值是什么,那么其他儿子节点的元素值就什么,就实现了区间清空和区间加法。

    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #define MAXN 110000
    #define RG register
    using namespace std;
    struct node{
        int lz,l,r,sum[26];
    }a[MAXN*4];
    int n,q;
    char ch[MAXN];
    int chuan[MAXN],tot[26];
    
    inline void pushup(int xv){
        for(int i=0;i<=25;i++) a[xv].sum[i]=a[xv*2].sum[i]+a[xv*2+1].sum[i];
    }
    
    inline void pushdown(int xv,int x,int y){
        if(a[xv].lz){
            a[xv].lz=0;
            for(int i=0;i<=25;i++){
                if(a[xv].sum[i]==0) a[xv*2].sum[i]=a[xv*2+1].sum[i]=0;
                else a[xv*2].sum[i]=x,a[xv*2+1].sum[i]=y;
            }
            a[xv*2].lz=a[xv*2+1].lz=1;
        }
    }
    
    inline void build(int xv,int l,int r){
        if(l==r){
            a[xv].l=l,a[xv].r=r,a[xv].lz=0;
            memset(a[xv].sum,0,sizeof(a[xv].sum));
            a[xv].sum[chuan[l]]=1;
            return;
        }
        a[xv].l=l,a[xv].r=r;
        int mid=(l+r)/2;
        build(xv*2,l,mid),build(xv*2+1,mid+1,r);
        pushup(xv);
    }
    
    inline int query(int xv,int l,int r,int k){
        RG int L=a[xv].l,R=a[xv].r,mid=(L+R)/2;
        if(L==l&&R==r){
            return a[xv].sum[k];
        }
        pushdown(xv,mid-L+1,R-mid);
        if(r<=mid) return query(xv*2,l,r,k);
        else if(l>mid) return query(xv*2+1,l,r,k);
        else return query(xv*2,l,mid,k)+query(xv*2+1,mid+1,r,k);
    }
    
    inline void update(int xv,int l,int r,int k){
        RG int L=a[xv].l,R=a[xv].r,mid=(L+R)/2;
        if(l==L&&R==r){
            memset(a[xv].sum,0,sizeof(a[xv].sum));
            a[xv].sum[k]=r-l+1;
            a[xv].lz=1;
            return;
        }
        pushdown(xv,mid-L+1,R-mid);
        if(r<=mid) update(xv*2,l,r,k);
        else if(l>mid) update(xv*2+1,l,r,k);
        else update(xv*2,l,mid,k),update(xv*2+1,mid+1,r,k);
        pushup(xv);
    }
    
    inline int query2(int xv,int ps){
        RG int L=a[xv].l,R=a[xv].r,mid=(L+R)/2;
        if(L==R){
            for(int i=0;i<=25;i++)
                if(a[xv].sum[i]) return i;
        }
        pushdown(xv,mid-L+1,R-mid);
        if(ps<=mid) return query2(xv*2,ps);
        else return query2(xv*2+1,ps);
    }
    
    int main()
    {
        scanf("%d%d",&n,&q);
        scanf("%s",ch+1);
        for(int i=1;i<=n;i++) chuan[i]=ch[i]-'a';
        build(1,1,n);
        while(q--){
            int l,r,x;scanf("%d%d%d",&l,&r,&x);
            if(l>r) swap(l,r);
            memset(tot,0,sizeof(tot));
            for(int i=0;i<=25;i++) tot[i]+=query(1,l,r,i);
            if(x==1){
                int ll=l,rr=l-1;
                for(int i=0;i<=25;i++){
                    if(tot[i]!=0){
                        rr+=tot[i];
                        update(1,ll,rr,i);
                        ll=rr+1;
                    }
                }
            }
            else{
                int ll=l,rr=l-1;
                for(int i=25;i>=0;i--){
                    if(tot[i]!=0){
                        rr+=tot[i];
                        update(1,ll,rr,i);
                        ll=rr+1;
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            printf("%c",query2(1,i)+'a');
        }
        return 0;
    }
  • 相关阅读:
    Chrome V75V76新版无法存为mhtml格式解决办法
    RHEL7 的注册
    JQuery淡入淡出 banner切换特效
    怎样把小坚果做成大生意
    黄页前台联动菜单修改时不能显示,要重新选择|没样式
    V9任何页面GET调用内容分页的说明
    phpcms v9 自定义伪静态的分页函数
    phpcms v9 自定义分页 带下拉跳转
    discuz X2.5自己写代码,获取当前登录的用户信息
    discuz!X2.5技术文档
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7643220.html
Copyright © 2020-2023  润新知