zoukankan      html  css  js  c++  java
  • string

                                                          string

    题目描述

    给定一个由小写字母组成的字符串s。有m次操作,每次操作给定3个参数l,r,x 。如果x=1,将 s[l]~s[r]升序排序;如果x=0,将s[l]~s[r]降序排序。你需要求出最终序列。

    输入格式

    第一行两个整数n,m,表示字符串长度为n,有m次操作。
    第二行一个字符串 。
    接下来 行每行三个整数l,r,x。

     

    输出格式

    一行一个字符串表示答案。

    样例

    样例输入

    5 2
    cabcd
    1 3 1
    3 5 0
    

    样例输出

    abdcc
    

    数据范围与提示

    对于100%的数据, n,m<=100000

    思路:首先想到的是用sort水,不过sort是nlogn,所以只能谁40分。

       正解:线段树,用线段树维护一段区间内字母的个数,这时tree[maxn]数组记录的不是区间和而是如果tree[rt]统治的区间内符号相同,则tree[rt]为此符号的值类似于lazy标记(这样做为了优化一下时间效率)

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=100000+10;
     4 char s[maxn];
     5 int tree[maxn<<2],f[maxn],n;
     6 void Build(int rt,int l,int r){
     7     if(l==r){
     8         tree[rt]=s[l]-'a'+1;//注意要加1,不然若这个字符为a的话,tree为0,区分不出有没有字符标记
     9         return ;
    10     }
    11     int mid=(l+r)>>1;
    12     Build(rt<<1,l,mid);
    13     Build(rt<<1|1,mid+1,r);
    14     if(tree[rt<<1]==tree[rt<<1|1]) tree[rt]=tree[rt<<1];//若左右子树相等,更新根节点
    15 }
    16 void pushdown(int rt,int l,int r){
    17     if(tree[rt]){
    18         tree[rt<<1]=tree[rt];
    19         tree[rt<<1|1]=tree[rt];
    20         tree[rt]=0;
    21     }
    22 }
    23 void query(int rt,int l,int r,int s,int t){
    24     if(s<=l&&t>=r&&tree[rt]){//若tree有值,再return
    25         f[tree[rt]]+=(r-l+1);
    26         return ;
    27     }
    28     pushdown(rt,l,r);
    29     int mid=(l+r)>>1;
    30     if(s<=mid) query(rt<<1,l,mid,s,t);
    31     if(t>mid) query(rt<<1|1,mid+1,r,s,t);
    32 }
    33 void Modify(int rt,int l,int r,int s,int t,int w){
    34     if(s<=l&&t>=r||tree[rt]==w){//写tree[rt]==w,会快一点
    35         tree[rt]=w;
    36         return;
    37     }
    38     pushdown(rt,l,r);
    39     int mid=(l+r)>>1;
    40     if(s<=mid) Modify(rt<<1,l,mid,s,t,w);
    41     if(t>mid) Modify(rt<<1|1,mid+1,r,s,t,w);
    42     if(tree[rt<<1]==tree[rt<<1|1]) tree[rt]=tree[rt<<1];
    43 }
    44 void solve(int l,int r,int x){
    45     memset(f,0,sizeof(f));//记得初始化
    46     query(1,1,n,l,r);//查询每个字母的数量
    47     if(x==1){
    48         int sum=l;
    49         for(int i=1;i<=26;i++){
    50             if(f[i]){
    51                 Modify(1,1,n,sum,sum+f[i]-1,i);
    52                 sum+=f[i];
    53             }
    54         }
    55     }//正序,正着枚举
    56     else{
    57         int sum=l;
    58         for(int i=26;i>=1;i--){
    59             if(f[i]){
    60                 Modify(1,1,n,sum,sum+f[i]-1,i);
    61                 sum+=f[i];
    62             }
    63         }
    64     }//倒序,倒着枚举
    65 }
    66 void print(int rt,int l,int r){
    67     if(tree[rt]){
    68         for(int i=l;i<=r;i++){
    69             printf("%c",tree[rt]+'a'-1);
    70         }
    71         return;
    72     }
    73     int mid=(l+r)>>1;
    74     print(rt<<1,l,mid);
    75     print(rt<<1|1,mid+1,r);
    76 }
    77 int main(){
    78     int m;
    79     scanf("%d%d",&n,&m);
    80     scanf("%s",s+1);
    81     Build(1,1,n);
    82     for(int i=1;i<=m;i++){
    83         int l,r,x;
    84         scanf("%d%d%d",&l,&r,&x);
    85         solve(l,r,x);
    86     }
    87     print(1,1,n);
    88     printf("
    ");
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    CTF-1-5题笔记
    无相劫指:Web安全之其他专题—第七天
    七伤拳:Web安全之文件包含漏洞专题—第六天
    CTF-输入密码查看flag -80
    工业级路由器采用的协议和功能
    PLC模拟量采集模块在工控领域的应用
    串口服务器的作用和工作原理是什么
    在PLC中开关量采集模块的作用
    4G DTU和4G工业路由器有哪些区别?
    应该怎么提升4G工业路由器的无线信号?
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13423205.html
Copyright © 2011-2022 走看看