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. 【LeetCode】240-搜索二维矩阵 II

    题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 m ...

  2. 致初学者(二): HDU 2014~ 2032题解

    下面继续给出HDU 2014~2032的AC程序,供大家参考.2014~2032这19道题就被归结为“C语言程序设计练习(三) ”~“C语言程序设计练习(五) ”. HDU 2014:青年歌手大奖赛_ ...

  3. Java 最常见 200+ 面试题答案全解析-面试必备

    本文分为十九个模块,分别是: Java 基础.容器.多线程.反射.对象拷贝.Java Web .异常.网络.设计模式.Spring/Spring MVC.Spring Boot/Spring Clou ...

  4. SqlServer2014怎样还原数据库

    场景 在SqlServer2014企业版上怎样进行数据库的还原,首先你得有一个其他数据 的备份文件. 实现 打开cmd,输入sql,打开SqlServer 2014 Management Studio ...

  5. a417: 螺旋矩陣

    题目: 每行有一正整数T,代表有几组测试数据 接下来有T行,每行有N.M两正整数 N为矩阵长宽,就是会有N*N矩阵 M为方向,M=1为顺时钟,M=2为逆时钟 N范围为1~100之间 思路: 所以,代码 ...

  6. Java多线程(十四):Timer

    Timer schedule(TimerTask task, Date time) 该方法在指定日期执行任务,如果是过去的时间,这个任务会立即被执行. 执行时间早于当前时间 示例代码,当前时间是201 ...

  7. Mybatis值ResultMap的使用详解

    Mybatis的定义 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  8. linux 操作系统级别监控 nmon命令

    nmon是IBM公司开发的Linux性能监控工具,可以实时展示系统性能情况,也可以将监控数据写入文件中,并使用nmon分析器做数据展示 实时监控 命令 ./nmon c 代表CPU m 代表Memor ...

  9. 机器学习之SVM调参实例

    一.任务 这次我们将了解在机器学习中支持向量机的使用方法以及一些参数的调整.支持向量机的基本原理就是将低维不可分问题转换为高维可分问题,在前面的博客具体介绍过了,这里就不再介绍了. 首先导入相关标准库 ...

  10. Javascript的基础

    ECMAScript(语法.标准) BOM(浏览器) DOM(网页) ECMAScript是一个标准,它规定了语法.类型.语句.关键字.保留子.操作符.对象.(相当于法律) BOM(浏览器对象模型): ...