JZOJ P5829 HZOI 20190801 A string 线段树
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 线段树的更多相关文章
- 考试题string——线段树。
string[题目描述]给定一个由小写字母组成的字符串 s.有 m 次操作,每次操作给定 3 个参数 l,r,x.如果 x=1,将 s[l]~s[r]升序排序;如果 x=0,将 s[l]~s[r]降序 ...
- string [线段树优化桶排]
题意大概是给你一个字符串,1e5次修改,每次给一个区间升序排列或降序排列,最后输出这个字符串; 其实是个挺裸的线段树优化题;但是我没有意识去结合桶排,扑该..... 首先 1.40分算法 O(NMlo ...
- hdu3973 AC's String 线段树+字符串hash
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...
- 【模拟8.01】string(线段树)
因为题中只有a-z,所以区间中大量字母都是重复的,我们不妨利用桶的性质. 开一棵树,里面维护当前区间内的相同元素,若区间内元素不同,则为零 每次升序操作就先查询一遍区间,用桶将每个区间的a-z元素统计 ...
- HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...
- HDU 6096 String 排序 + 线段树 + 扫描线
String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...
- [jzoj 5662] 尺树寸泓 解题报告 (线段树+中序遍历)
interlinkage: https://jzoj.net/senior/#contest/show/2703/1 description: solution: 发现$dfs$序不好维护 注意到这是 ...
- [jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)
题目链接: https://jzoj.net/senior/#main/show/6086 题目: 题解: 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘 这样的子树 ...
- HDU - 3973 AC's String(Hash+线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=3973 题意 给一个词典和一个主串.有两种操作,查询主串某个区间,问这主串区间中包含多少词典中的词语.修改主串某一 ...
随机推荐
- 启动web项目,监听器、过滤器、拦截器启动顺序
启动顺序:监听器 > 过滤器 > 拦截器 记忆技巧:接到命令,监听电报,过滤敌情,拦截行动.
- SQL Server 添加数据库没有权限等
{ 在安装好sql 后 第一次需要用windows 方式登陆 1.创建一个宁外一个登陆名登陆 在安全->登陆名 2.给此登陆属性的服务器角色添加sysadmin权限 //尽情享受!!! }
- tornado接收ajax的post请求报错WARNING:tornado.access:405 OPTIONS /add
后端报错信息 WARNING:tornado.access:405 OPTIONS /add (::1) 1.00m 前端报错信息 2xhr.js?ec6c:172 OPTIONS http://lo ...
- SpringCloud及其五大常用组件之Feign、Ribbon和Hystrix
1.Feign 我们已经将Eureka和Zuul开发完毕,而且上面注册了两个微服务,现在我们实现两个微服务之间的调用. String baseUrl = "http://127.0.0.1: ...
- Docker系列(七):Docker图形化管理和监控
Docker管理工具之官方三剑客 Docker Machine是什么鬼 从前 现在 你需要登录主机,按照主机及操作系统特有的安装以及配置步骤安装Docker,使其 能运行Docker容器. Docke ...
- 访问配置信息的URL与配置文件的映射关系
- IK分词器插件
(1)源码 https://github.com/medcl/elasticsearch-analysis-ik (2)releases https://github.com/medcl/elast ...
- git push到多个不同的远程仓库
1.若现在本地有一个已经和github远程仓库关联好的本地仓库,平时都会将本地仓库push到github上. 2.有一天突然发现"码云"这个远程仓库网站,咦!这个还可以创建priv ...
- mybatis中处理结果集映射
单行结果集映射: 接口中方法返回值定义为Map类型,sql语句的resultType属性设置为map即可.这种情况默认把列名作为key,列中的值作为value. 也就是说用map<Strirng ...
- DOM节点的创建、插入、删除
值得注意的是:节点的创建.插入以及删除都是操作父级容器.(1)创建var newDiv = documnet.createElement('div'); ——创建的元素只能操作一次 (2)插入/追加a ...