zoukankan      html  css  js  c++  java
  • [线段树] Jzoj P5829 string

    Description

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

    Input

    第一行两个整数 n,m。第二行一个字符串 s。接下来 m 行每行三 个整数 l,r,x。

    Output

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

    Sample Input

    5 2
    cabcd
    1 3 1
    3 5 0 

    Sample Output

    abdcc
     

    Data Constraint

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

    题解

    • 可以建一棵线段树
    • 把各个叶子节点就是对应字母的值
    • 然后对于一个节点,如果其两个子节点的数值相同,那么它自己也附上相同的值
    • 更改时如果区间不完全重合,那么就需要把其子孩子附上它的值
    • 然后对于每一次操作,求其区间内各个字母的次数
    • 然后按照要求从a-z或从z-a循环,依次替换线段树中的位置

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 struct edge{int l,r,v;}tree[400010];
     7 char s[100010];
     8 int n,m,f[30];
     9 void build(int l,int r,int d)
    10 {
    11     tree[d].l=l,tree[d].r=r;
    12     if (l==r)
    13     {
    14         tree[d].v=s[l]-'a'+1;
    15         return;
    16     }
    17     int mid=(l+r)/2;
    18     build(l,mid,d*2),build(mid+1,r,d*2+1);
    19     if (tree[d*2].v==tree[d*2+1].v) tree[d].v=tree[d*2].v;
    20 }
    21 void getnum(int l,int r,int d)
    22 {
    23     if (tree[d].l>=l&&tree[d].r<=r&&tree[d].v!=0)
    24     {
    25         f[tree[d].v]+=tree[d].r-tree[d].l+1;
    26         return;
    27     }
    28     if (tree[d].v) tree[d*2].v=tree[d].v,tree[d*2+1].v=tree[d].v;
    29     int mid=(tree[d].l+tree[d].r)/2;
    30     if (mid>=l) getnum(l,r,d*2);
    31     if (mid<r) getnum(l,r,d*2+1);
    32 }
    33 void change(int l,int r,int d,int x)
    34 {
    35     if (tree[d].l>=l&&tree[d].r<=r||tree[d].v==x)
    36     {
    37         tree[d].v=x;
    38         return;
    39     }
    40     if (tree[d].v) tree[d*2].v=tree[d].v,tree[d*2+1].v=tree[d].v,tree[d].v=0;
    41     int mid=(tree[d].l+tree[d].r)/2;
    42     if (l<=mid) change(l,r,d*2,x);
    43     if (mid<r) change(l,r,d*2+1,x);
    44     if (tree[d*2].v==tree[d*2+1].v) tree[d].v=tree[d*2].v;
    45 }
    46 void out(int d)
    47 {
    48     if (tree[d].v)
    49     {
    50         for (int i=1;i<=tree[d].r-tree[d].l+1;i++) printf("%c",tree[d].v+'a'-1);
    51         return;
    52     }
    53     out(d*2),out(d*2+1);
    54 }
    55 int main()
    56 {
    57     freopen("string.in","r",stdin);
    58     freopen("string.out","w",stdout);
    59     scanf("%d%d",&n,&m);
    60     scanf("%s",s+1);
    61     build(1,n,1);
    62     for (int j=1;j<=m;j++)
    63     {
    64         int l,r,x;
    65         scanf("%d%d%d",&l,&r,&x);
    66         memset(f,0,sizeof(f));
    67         getnum(l,r,1);
    68         if (x==1)
    69             for (int i=1;i<=26;i++)
    70             {
    71                 if (f[i]) change(l,l+f[i]-1,1,i),l=l+f[i];
    72             }
    73         else 
    74             for (int i=26;i>=1;i--)
    75             {
    76                 if (f[i]) change(l,l+f[i]-1,1,i),l=l+f[i];
    77             }
    78     }
    79     out(1);
    80     return 0;
    81 }
  • 相关阅读:
    JavaScript 中document.write() 详细用法介绍
    教你怎么用JavaScript检测当前浏览器是无头浏览器
    JavaScript网页截屏方法,你get到了嘛?
    新手小白该怎么学习前端?附学习路线和资料
    实现微前端需要了解的 Vue Genesis 渲染器
    前端新人关注的Web前端饱和性分析?前端面试必知必会的十点!
    这个前端竟然用动态规划写瀑布流布局?给我打死他!
    Kubernetes之Ingress+Traefik
    MySQL语法大全
    PPTP服务器
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9498326.html
Copyright © 2011-2022 走看看