Codeforces 558E A Simple Task(计数排序+线段树优化)
http://codeforces.com/problemset/problem/558/E
Examples
input 1
abacdabcda
output 1
cbcaaaabdd
input 2
agjucbvdfk
output 2
abcdfgjkuv
题意:
给出一个字母的序列(只包含小写字母),每次对它的一个区间进行排序(递增或递减),问最后的字母序列。
自闭题,身为蒟蒻的我读完题后单纯的觉得这题如名字一一样一个简单的任务(完全没有意识到问题的严重性),直接sort走起,结果。。。该题数据规模很大 排序是关键,要想到计数排序
看了题解,真好,26颗线段树,人否?
题解:
采用计数排序的复杂度是O(n∗q),无法通过,但有所启示。
可以看出计数就是区间求和,排序就是区间更新,可以用线段树维护。
做法是建立26棵线段树,第i棵树维护第i个字母的位置信息。
计数时,在26棵线段树内对[L,R]分别做一次查询,统计区间[L,R]中每个字母的个数,排序时根据递增还是递减,在相应的区间内按照字母的顺序(升序或降序)依次重新填进区间内。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <queue>
#include <set>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const double PI=acos(-);
const int maxn=1e5+;
using namespace std; int n,q;
char str[maxn]; struct Tree
{
int sum;
int l;
int r;
int lazy;
}; struct SegmentTree
{
Tree tree[maxn<<];
void PushUp(int rt)
{
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
void PushDown(int rt)
{
int lazy=tree[rt].lazy;
if(lazy!=-)
{
tree[rt<<].lazy=tree[rt<<|].lazy=lazy;
tree[rt<<].sum=(tree[rt<<].r-tree[rt<<].l+)*lazy;
tree[rt<<|].sum=(tree[rt<<|].r-tree[rt<<|].l+)*lazy;
tree[rt].lazy=-;
}
}
void Build(int rt,int l,int r,int id)//建树
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].lazy=-;
if(l==r)
{
if(str[l]-'a'==id) tree[rt].sum=;
else tree[rt].sum=;
return ;
}
int m=(l+r)>>;
Build(rt<<,l,m,id);
Build(rt<<|,m+,r,id);
PushUp(rt);
}
void Update(int rt,int L,int R,int v)//区间更新
{
int l=tree[rt].l;
int r=tree[rt].r;
if(L<=l&&R>=r)
{
tree[rt].sum=(r-l+)*v;
tree[rt].lazy=v;
return ;
}
PushDown(rt);
int m=(l+r)>>;
if(L<=m&&R>=l)
Update(rt<<,L,R,v);
if(R>m&&L<=r)
Update(rt<<|,L,R,v);
PushUp(rt);
}
int Query(int rt,int L,int R)//区间查询
{
int l=tree[rt].l;
int r=tree[rt].r;
if(L<=l&&R>=r)
return tree[rt].sum;
PushDown(rt);
int m=(l+r)>>;
int sum=;
if(L<=m&&R>=l)
sum+=Query(rt<<,L,R);
if(R>m&&L<=r)
sum+=Query(rt<<|,L,R);
return sum;
}
}SegTree[]; int main()
{
scanf("%d %d",&n,&q);
scanf("%s",str+);
for(int i=;i<;i++)//建立26个线段树
{
SegTree[i].Build(,,n,i);
}
while(q--)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
int num[];//记录区间内每个字母的个数
for(int i=;i<;i++)
{
num[i]=SegTree[i].Query(,a,b);
SegTree[i].Update(,a,b,);//将该区间内的字母消去
}
int l=a;//l指向要填入区间的头
if(c)//升序填入
{
for(int i=;i<;i++)
{
SegTree[i].Update(,l,l+num[i]-,);
l+=num[i];
}
}
else//降序填入
{
for(int i=;i>=;i--)
{
SegTree[i].Update(,l,l+num[i]-,);
l+=num[i];
}
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<;j++)
{
if(SegTree[j].Query(,i,i))
{
printf("%c",j+'a');
}
}
}
printf("\n");
return ;
}
Codeforces 558E A Simple Task(计数排序+线段树优化)的更多相关文章
- Codeforces 558E A Simple Task (计数排序&&线段树优化)
题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...
- CodeForces 558E(计数排序+线段树优化)
题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...
- 计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task
E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作, ...
- Nowcoder Hash Function ( 拓扑排序 && 线段树优化建图 )
题目链接 题意 : 给出一个哈希表.其避免冲突的方法是线性探测再散列.现在问你给出的哈希表是否合法.如果合法则输出所有元素插入的顺序.如果有多解则输出字典序最小的那一个.如果不合法则输出 -1 分析 ...
- Codeforces 1603D - Artistic Partition(莫反+线段树优化 dp)
Codeforces 题面传送门 & 洛谷题面传送门 学 whk 时比较无聊开了道题做做发现是道神题( 介绍一种不太一样的做法,不观察出决策单调性也可以做. 首先一个很 trivial 的 o ...
- Codeforces.1045A.Last chance(最大流ISAP 线段树优化建图)
题目链接 \(Description\) 你需要用给定的\(n\)个武器摧毁\(m\)架飞船中的某一些.每架飞船需要被摧毁恰好一次. 武器共三种:1.可以在给定的集合中摧毁一架飞船:2.可以摧毁区间\ ...
- Codeforces 558E A Simple Task(权值线段树)
题目链接 A Simple Task 题意 给出一个小写字母序列和若干操作.每个操作为对给定区间进行升序排序或降序排序. 考虑权值线段树. 建立26棵权值线段树.每次操作的时候先把26棵线段树上的 ...
- codeforces 558E A Simple Task 线段树
题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...
- Codeforces 558E A Simple Task
题意:给定一个字符串,以及m次操作,每次操作对字符串的一个子区间进行升序或降序排序,求m次操作后的串 考虑桶排,发现线段树可以模拟桶排的过程,所以对26个字母分别建立线段树即可 #include< ...
随机推荐
- Java中String类为什么被设计为final?
Java中String类为什么被设计为final 首先,String是引用类型,也就是每个字符串都是一个String实例.通过源码可以看到String底层维护了一个byte数组:private f ...
- 滴滴与Uber都盯上拉美市场!一场惨烈竞争谁能胜出?
创业者最怕的是什么?或许并不是在创业初期的艰难历程.毕竟在初期虽然会遇到很多磨难和众多竞争对手,但只要敢打敢拼就有胜出的可能.创业者最怕的或许是成为所属行业独角兽后,要面对势均力敌对手的凶猛攻击!大家 ...
- Mac Github:第一次上传成功,解决图片不可显示,Initial commit Untracked files
在上传之前需要先给自己的电脑安装SSH 上传成功用的是github的官方提示,直接复制去做就可以了 解决README.md中图片不可显示:图片路径到底要怎么写? https://blog.csdn.n ...
- mysql插入文本文档及读取
1.把本地的一个文件插入到数据库中,数据库字段用text保存 public static void main(String[] args) { PropKit.use(“pro.txt”);Druid ...
- C语言-指针到底是什么?
1.指针到底是什么?(1).指针变量与普通变量的区别 指针的实质就是一个变量,他跟普通变量没有任何本质区别.指针完整的名字应该叫做指针变量,简称为指针.2.为什么需要指针?(1).指针的出现是为了实现 ...
- Python笔记_第四篇_高阶编程_进程、线程、协程_2.线程
1. 线程概述: 在一个进程的内部,要同时干多件事情,就需要同时运行“多个子任务”,我们把进程内的这些“子任务”叫做线程.也就说线程是进程成的子任务. 线程通常叫做情景的进程.线程是通过向内侧控件的并 ...
- mqtt+htttp+websocket
一.介绍 1.参考网址1:WebSocket协议:5分钟从入门到精通 2.参考网址2:WebSocket 教程(阮一峰) 二.应用 1.参考网址1:从 HTTP 到 MQTT:一个移动后端案例概述 2 ...
- Spring Bean的生命周期、Spring MVC的工作流程、IOC,AOP
1.Spring Bean的生命周期? (1)构造方法实例化bean. (2)构造方法设置对象属性. (3)是否实现aware接口,三种接口(BeanNameAware,BeanFactoryAwar ...
- UVALive 2678 利用序列的前缀来减少时间复杂度
题意很简单,在一串正整数序列中找一个连续的子序列使该序列和大于等于一个已知量S,但要求序列长度最短,通常喜欢暴力枚举 这个题目跟大白书之前的一个题目很像,在数列A中 求 Ai-Aj最大 并且 i< ...
- lvm镜像卷
镜像能够分配物理分区的多个副本,从而提高数据的可用性.当某个磁盘发生故障并且其物理分区变为不可用时,你仍然可以访问可用磁盘上的镜像数据.LVM在逻辑卷内执行镜像. 系统版本 # cat /etc/ce ...