JZOJ P5829 A. string

题面:https://www.cnblogs.com/Juve/articles/11286476.html

考场上想起了排序这道题:https://www.cnblogs.com/Juve/p/11269638.html

n遍二分?

亲测TLE,0分

你暴力sort都有40分

当然这题不用这样

我们借鉴排序的思路

我们用线段树来完成操作,那么我们想线段树存什么,懒标记是什么

借鉴刚才那道题,我们将节点信息和懒标记合二为一

设tr[k].val,如果k管辖的区间里的字母都是同一个字母,则tr[k].val就是那个字母,否则tr[k].val=0,

这样十分方便维护:

down:

if(!tr[k].val) return ;
tr[k<<1].val=tr[k<<1|1].val=tr[k].val;

up:

if(tr[k<<1].val==tr[k<<1|1].val)
tr[k].val=tr[k<<1].val;

我们每次对于一次排序[L,R],查询[L,R],中26个字母出现的次数cnt[i],

实现:

if(opl<=l&&r<=opr&&tr[k].val){
cnt[tr[k].val]+=(r-l+1);
return ;
}

如果升序,就把[L,R]中前cnt[a]修改成a,接下来cnt[b]修改成b,。。。。。。

降序就反过来

最后输出也是一遍线段树dfs,然后。。。其实没什么了

来代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAXN 100005
#define re register
using namespace std;
int n,m,a[MAXN],cnt[28];
char ch[MAXN]
struct Segtree{
int l,r,val;
}tr[MAXN<<2];
void down(int k,int data){
if(!tr[k].val) return ;
tr[k<<1].val=tr[k<<1|1].val=tr[k].val;
tr[k].val=data;
}
void build(int k,int l,int r){
tr[k].l=l,tr[k].r=r;
if(l==r){
tr[k].val=a[l];
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r);
if(tr[k<<1].val==tr[k<<1|1].val)
tr[k].val=tr[k<<1].val;
}
void get_cnt(int k,int opl,int opr){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr&&tr[k].val){
cnt[tr[k].val]+=(r-l+1);
return ;
}
down(k,tr[k].val);
int mid=(l+r)>>1;
if(opl<=mid) get_cnt(k<<1,opl,opr);
if(opr>mid) get_cnt(k<<1|1,opl,opr);
}
void change(int k,int opl,int opr,int data){
if(tr[k].val==data) return ;
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
tr[k].val=data;
return ;
}
down(k,0);
int mid=(l+r)>>1;
if(opl<=mid) change(k<<1,opl,opr,data);
if(opr>mid) change(k<<1|1,opl,opr,data);
if(tr[k<<1].val==tr[k<<1|1].val)
tr[k].val=tr[k<<1].val;
}
void print(int k){
if(tr[k].val){
int l=tr[k].l,r=tr[k].r;
for(int i=l;i<=r;i++)
putchar(tr[k].val-1+'a');
return ;
}
print(k<<1),print(k<<1|1);
}
int main(){
scanf("%d%d",&n,&m);
scanf("%s",ch+1);
for(re int i=1;i<=n;i++)
a[i]=ch[i]-'a'+1;
build(1,1,n);
for(re int i=1,x,l,r;i<=m;i++){
scanf("%d%d%d",&l,&r,&x);
memset(cnt,0,sizeof(cnt));
get_cnt(1,l,r);
if(x==0){
for(re int j=26;j>=1;j--){
change(1,l,l+cnt[j]-1,j);
l+=cnt[j];
}
}else{
for(re int j=1;j<=26;j++){
change(1,l,l+cnt[j]-1,j);
l+=cnt[j];
}
}
}
print(1);
puts("");
return 0;
}

JZOJ P5829 HZOI 20190801 A string 线段树的更多相关文章

  1. 考试题string——线段树。

    string[题目描述]给定一个由小写字母组成的字符串 s.有 m 次操作,每次操作给定 3 个参数 l,r,x.如果 x=1,将 s[l]~s[r]升序排序;如果 x=0,将 s[l]~s[r]降序 ...

  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. [jzoj 5662] 尺树寸泓 解题报告 (线段树+中序遍历)

    interlinkage: https://jzoj.net/senior/#contest/show/2703/1 description: solution: 发现$dfs$序不好维护 注意到这是 ...

  8. [jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)

    题目链接: https://jzoj.net/senior/#main/show/6086 题目: 题解: 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘 这样的子树 ...

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

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

随机推荐

  1. jupyter|魔法函数问题| UsageError: Line magic function `%` not found

    问题: jupyter notebook 使用魔法函数% matplotlib inline,报错:UsageError: Line magic function `%` not found 解决: ...

  2. csp-s模拟测试60

    csp-s模拟测试60       2019-10-05 RT. 又颓又垃圾. 状态低迷,题都交不上去. 交了也是爆零,垃圾玩家没有什么可说的,就是垃圾. A. 嘟嘟噜 $mlogn$的毒瘤做法. 贴 ...

  3. 尚学linux课程---4、linux网络配置及linux文件

    尚学linux课程---4.linux网络配置及linux文件 一.总结 一句话总结: linux下的etc目录是配置文件的目录,所以很多的文件配置操作都可以看到它的身影:比如 init系列命名,比如 ...

  4. System.Web.Mvc.HttpGetAttribute.cs

    ylbtech-System.Web.Mvc.HttpGetAttribute.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, P ...

  5. 阿里云CentOs7上安装JDK

    一.查看服务器是否已经预装了JDK 在拿到新机器以后,要先看下机器上是否已经预装了JDK,命令: rpm -qa|grep jdk 如果有的话,卸载openjdk(无需输全称).命令: yum -y ...

  6. 访问配置信息的URL与配置文件的映射关系

  7. 左神算法基础班4_1&2实现二叉树的先序、中序、后序遍历,包括递归方式和非递归

    Problem: 实现二叉树的先序.中序.后序遍历,包括递归方式和非递归方式 Solution: 切记递归规则: 先遍历根节点,然后是左孩子,右孩子, 根据不同的打印位置来确定中序.前序.后续遍历. ...

  8. java8 新特性学习笔记

    Java8新特性 学习笔记 1主要内容 Lambda 表达式 函数式接口 方法引用与构造器引用 Stream API 接口中的默认方法与静态方法 新时间日期 API 其他新特性 2 简洁 速度更快 修 ...

  9. <linux常用命令>初级版

    显示时间 date 显示日历cal 变换目录 cd 显示当前所在目录 pwd 建立新目录 mkdir -p a/b/c 删除空目录 rmdir 当前目录下文件和目录显示 ls 复制 cp 文件 路径 ...

  10. 面试系列14 redis的过期策略都有哪些

    (1)设置过期时间 我们set key的时候,都可以给一个expire time,就是过期时间,指定这个key比如说只能存活1个小时?10分钟?这个很有用,我们自己可以指定缓存到期就失效. 如果假设你 ...