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. (转)JNI入门教程之HelloWorld篇 .

    转: http://blog.csdn.net/mingjava/article/details/180946 本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第 ...

  2. 尚学linux课程---3、linux网络说明

    尚学linux课程---3.linux网络说明 一.总结 一句话总结: 如果NAT模式:linux,VMnet8,虚拟出来的路由器 要在同一个网段, 那么 linux才能 通过 网络地址转换 经过wi ...

  3. (一)通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)

    (一)通过JAVA连接SAP调用接口 (sapjco3.jar在Windows和MacOS上的配置) 一.sapjoc3.jar获取 由于sap官网提供的链接需要合作公司提供账号密码,如果商用请索要正 ...

  4. JS switch 分支语句

    描述:根据一个变量的不同取值,来执行不同的代码. 语法结构: switch(变量) { case 值1: 代码1; break; case 值2: 代码2; break; case 值3: 代码3; ...

  5. LightOJ-1138-Trailing Zeroes (III)-二分+求N!末尾0

    You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in d ...

  6. Collection单列集合中的常用实现类

    Collection 集合层次的根接口 List 有序 有索引 可以重复 ArrayList 底层数据结构是数组 查询快 增删快 线程不安全 效率高 LinkedList 底层数据结构是链表 查询慢 ...

  7. Java 高级面试知识点汇总!

    1.常用设计模式 单例模式:懒汉式.饿汉式.双重校验锁.静态加载,内部类加载.枚举类加载.保证一个类仅有一个实例,并提供一个访问它的全局访问点. 代理模式:动态代理和静态代理,什么时候使用动态代理. ...

  8. springboot整合jpa和mybatis实现主从复制

    百度多方参考终于配出我自己的了,以下仅供参考 参考https://www.cnblogs.com/cjsblog/p/9712457.html 代码 首先数据源配置 spring.datasource ...

  9. [洛谷P3672]小清新签到题

    题目描述 题目还是简单一点好. 给定自然数n.k.x,你要求出第k小的长度为n的逆序对对数为x的1~n的排列a1,a2...an,然后用仙人图上在线分支定界启发式带花树上下界最小费用流解决问题,保证存 ...

  10. 【学术篇】状态压缩动态规划——POJ3254/洛谷1879 玉米田Corn Field

    我要开状压dp的坑了..直播从入门到放弃系列.. 那就先拿一道状压dp的水题练练手吧.. 然后就找到了这一道..这道题使我清醒地认识到阻碍我的不是算法,而是视力= = 传送门: poj:http:// ...