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[];
}a[MAXN*];
int n,q;
char ch[MAXN];
int chuan[MAXN],tot[]; inline void pushup(int xv){
for(int i=;i<=;i++) a[xv].sum[i]=a[xv*].sum[i]+a[xv*+].sum[i];
} inline void pushdown(int xv,int x,int y){
if(a[xv].lz){
a[xv].lz=;
for(int i=;i<=;i++){
if(a[xv].sum[i]==) a[xv*].sum[i]=a[xv*+].sum[i]=;
else a[xv*].sum[i]=x,a[xv*+].sum[i]=y;
}
a[xv*].lz=a[xv*+].lz=;
}
} inline void build(int xv,int l,int r){
if(l==r){
a[xv].l=l,a[xv].r=r,a[xv].lz=;
memset(a[xv].sum,,sizeof(a[xv].sum));
a[xv].sum[chuan[l]]=;
return;
}
a[xv].l=l,a[xv].r=r;
int mid=(l+r)/;
build(xv*,l,mid),build(xv*+,mid+,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)/;
if(L==l&&R==r){
return a[xv].sum[k];
}
pushdown(xv,mid-L+,R-mid);
if(r<=mid) return query(xv*,l,r,k);
else if(l>mid) return query(xv*+,l,r,k);
else return query(xv*,l,mid,k)+query(xv*+,mid+,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)/;
if(l==L&&R==r){
memset(a[xv].sum,,sizeof(a[xv].sum));
a[xv].sum[k]=r-l+;
a[xv].lz=;
return;
}
pushdown(xv,mid-L+,R-mid);
if(r<=mid) update(xv*,l,r,k);
else if(l>mid) update(xv*+,l,r,k);
else update(xv*,l,mid,k),update(xv*+,mid+,r,k);
pushup(xv);
} inline int query2(int xv,int ps){
RG int L=a[xv].l,R=a[xv].r,mid=(L+R)/;
if(L==R){
for(int i=;i<=;i++)
if(a[xv].sum[i]) return i;
}
pushdown(xv,mid-L+,R-mid);
if(ps<=mid) return query2(xv*,ps);
else return query2(xv*+,ps);
} int main()
{
scanf("%d%d",&n,&q);
scanf("%s",ch+);
for(int i=;i<=n;i++) chuan[i]=ch[i]-'a';
build(,,n);
while(q--){
int l,r,x;scanf("%d%d%d",&l,&r,&x);
if(l>r) swap(l,r);
memset(tot,,sizeof(tot));
for(int i=;i<=;i++) tot[i]+=query(,l,r,i);
if(x==){
int ll=l,rr=l-;
for(int i=;i<=;i++){
if(tot[i]!=){
rr+=tot[i];
update(,ll,rr,i);
ll=rr+;
}
}
}
else{
int ll=l,rr=l-;
for(int i=;i>=;i--){
if(tot[i]!=){
rr+=tot[i];
update(,ll,rr,i);
ll=rr+;
}
}
}
}
for(int i=;i<=n;i++){
printf("%c",query2(,i)+'a');
}
return ;
}

考试题string——线段树。的更多相关文章

  1. JZOJ P5829 HZOI 20190801 A string 线段树

    JZOJ P5829 A. string 题面:https://www.cnblogs.com/Juve/articles/11286476.html 考场上想起了排序这道题:https://www. ...

  2. string [线段树优化桶排]

    题意大概是给你一个字符串,1e5次修改,每次给一个区间升序排列或降序排列,最后输出这个字符串; 其实是个挺裸的线段树优化题;但是我没有意识去结合桶排,扑该..... 首先 1.40分算法 O(NMlo ...

  3. hdu3973 AC's String 线段树+字符串hash

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...

  4. 【模拟8.01】string(线段树)

    因为题中只有a-z,所以区间中大量字母都是重复的,我们不妨利用桶的性质. 开一棵树,里面维护当前区间内的相同元素,若区间内元素不同,则为零 每次升序操作就先查询一遍区间,用桶将每个区间的a-z元素统计 ...

  5. HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...

  6. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  7. HDU - 3973 AC's String(Hash+线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=3973 题意 给一个词典和一个主串.有两种操作,查询主串某个区间,问这主串区间中包含多少词典中的词语.修改主串某一 ...

  8. [CF1063F]String Journey[后缀数组+线段树]

    题意 在 \(S\) 中找出 \(t\) 个子串满足 \(t_{i+1}\) 是 \(t_{i}\) 的子串,要让 \(t\) 最大. \(|S| \leq 5\times 10^5\). 分析 定义 ...

  9. CF1063F. String Journey(后缀数组+线段树)

    题目链接 https://codeforces.com/contest/1063/problem/F 题解 虽然本题有时间复杂度较高但非常好写的做法...... 首先,若答案为 \(k\),则一定存在 ...

随机推荐

  1. 【Offer】[17] 【打印1到最大的n位数】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数即999. 思路分析 要考虑到大数问题, ...

  2. Mac环境IntelliJ IDEA配置JDK提示The selected directory is not a valid home for JDK

    笔者使用mac配置如下: 硬件环境:MacBook Pro 操作系统:MacOS Sierra 10.13.6 开发工具:IntelliJ IDEA 2016.x JDK版本:已有Open JDK 8 ...

  3. 网络编程之TCP/IP各层详解

    网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只 ...

  4. Java开学测试

    这次开学测试要求做一个信息系统,该系统完成学生成绩录入,修改,计算学分积点和查询学生成绩的简单功能. 下面是我写的代码 //信1805-3班 20183641 赵树琪 package test; im ...

  5. Java的8种基本数据类型的内存占用字节数和取值范围

    这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...

  6. 明明有class为什么还是报ClassNotFoundException?

    描述 我们修改接口时,习惯发布一个快照版本用于测试.我们的一个服务也是发布了快照版本,然后一个jar程序要依赖这个服务,修改pom文件打包部署后,通过 java -jar 命令执行这个jar程序,然后 ...

  7. 5、链表队列(java实现)

    1.图例 2.链表节点 public class Node<T> { public T data; public Node next; } 3.具体实现 public class Link ...

  8. Java-HashSet集合中的几种遍历方式

    //我们先创建一个set集合 public static void main(String[] args) { Set<Integer> sets = new HashSet<> ...

  9. Android Studio 3.1.3填坑之路

      昨天编写程序的时候,遇到了一个非常令人头疼的BUG,如下图:   标题栏和里面的内容都消失了,这对于一个非常在乎排版的软件来说简直就是晴空霹雳,搞了好长时间,终于在今天找到解决方法,原来是升级搞的 ...

  10. Linux 笔记 - 第十三章 Linux 系统日常管理之(四)Linux 中 rsync 工具和网络配置

    博客地址:http://www.moonxy.com 一.前言 rsync 命令是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机间的文件,可以理解为 remote sync(远程同步) ...