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< ...
随机推荐
- mysql第四篇:数据操作之单表查询
单表查询 一.简单查询 -- 创建表 DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `id` ) NOT NULL AUTO_INCRE ...
- 一天一个设计模式——Abstract Factory抽象工厂模式
一.模式说明 前面学习了工厂方法(Factory Method)模式.在工厂方法模式中,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理.这里学习的抽象工厂 ...
- Codeforces 1291A - Even But Not Even
题目大意: 给定一个字符串数字(很大) 问能不能删除一些数字(或者不删除) 使得剩余的数字各位数相加是偶数,但是这整个数字是个奇数 解题思路: 统计字符串中单个数字奇数的个数 分情况 个数为0或者1时 ...
- POJ 1745:Divisibility 枚举某一状态的DP
Divisibility Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11001 Accepted: 3933 Des ...
- JavaSE--Arrays.copyof
背景: 想偷懒一次数组赋值下面多个例子复制下数组就好了.. 以为 Arrays.copyof(Arrays.copyof内部调用的是 System.copy, 所以同 Arrays.copy)拷贝出来 ...
- zabbix监控一个机器上的多个java进程的jvm
一.监控安装部署 1.1 JVM端口配置 (/bqhexin/tomcat/bin/catalina.sh)在安装的tomcat路径,找到catalina.sh文件. vim编辑并添加: catali ...
- 学习Github必须要会的知识
目的 托管项目代码 基本概念 仓库Respository 存放项目代码,每个项目对应一个仓库,多个开源项目则有多个仓库. 收藏Star 收藏项目,方便下次查看. 复制克隆项目Fork ...
- Nginx复习
Nginx基本概念 是什么,做什么事情 高性能的HTTP和反向代理web服务器,特点占有内存小,并发能力强, Nginx专为性能优化而开发,最高支持50000个并发连接数 反向代理 正向代理 在客户 ...
- aliyun二级域名绑定
NameVirtualHost *:80 开启监听 <VirtualHost *:80> DocumentRoot /home/service/ ServerName serv ...
- java8+tomcate8仅支持TLSv1.2
1.编辑$tomcat_home/conf/server.xml <Connector protocol="org.apache.coyote.http11.Http11NioProt ...
