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. Spring Cloud Alibaba | 微服务分布式事务之Seata

    Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Green ...

  2. 一个例子明白 javascript 中 for 与 for in 的区别

    var arr = new Array(); arr["a"] = "aa"; arr["b"] = "bb"; arr ...

  3. Java多线程之原子操作类

    在并发编程中很容易出现并发安全问题,最简单的例子就是多线程更新变量i=1,多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchronized进行控制来达到线程安全 ...

  4. PHP 错误:Warning: Cannot modify header information - headers already sent by ...

    PHP初学者容易遇到的错误:Warning: Cannot modify header information - headers already sent by ...: 通常是由不正确使用 hea ...

  5. urllib2爬取图片成功之后不能打开

    经过8个小时的摸索,终于决定写下此随笔! 初学爬虫,准备爬取百度美女吧的图片,爬取图片之后发现打不开,上代码: import urllib import urllib2 from lxml impor ...

  6. Ubuntu18.04安装测试TensorFlow-GPU

    1 安装Ubuntu18.04.03 lts spt@spt-ts:~$ lsb_release -a No LSB modules are available. Distributor ID: Ub ...

  7. SWPU CTF题解

    本博客为西南石油大学(南充校区)CTF团队赛的题解 所有题目网址:http://47.106.87.69:9000/game 今天我是流泪狗狗头 解压后发现压缩包中是一个带有密码的图片,winhex分 ...

  8. Mysql高手系列 - 第13篇:细说NULL导致的神坑,让人防不胜防

    这是Mysql系列第13篇. 环境:mysql5.7.25,cmd命令中进行演示. 当数据的值为NULL的时候,可能出现各种意想不到的效果,让人防不胜防,我们来看看NULL导致的各种神坑,如何避免? ...

  9. 使用Nexus3搭建Maven私服

    1.搭建Maven私服背景 公司还是按捺不住,要搭建一个自己的Maven本地仓库,可以让开发人员down架包,从内网还是快很多. 这样公司的maven本地仓库就是 开发人员自己电脑上的maven仓库 ...

  10. Codeforces Numbers 题解

    这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...