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笔记01
			java对象数组 Student[] Students = new Student[3]; 与普通数组无差 java集合类 集合类: 面向对象对事物的描述是通过对象来体现的. 为了方便对多个对象进行操 ... 
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring CGLlB动态代理
			JDK 动态代理使用起来非常简单,但是它也有一定的局限性,这是因为 JDK 动态代理必须要实现一个或多个接口,如果不希望实现接口,则可以使用 CGLIB 代理. CGLIB(Code Generati ... 
- 51nod 1421:最大MOD值
			1421 最大MOD值 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以 ... 
- 十分简明易懂的FFT(快速傅里叶变换)
			https://blog.csdn.net/enjoy_pascal/article/details/81478582 FFT前言快速傅里叶变换 (fast Fourier transform),即利 ... 
- CTF -bugku-misc(持续更新直到全部刷完)
			1.签到题 点开可见.(这题就不浪费键盘了) CTF- 2.这是一张单纯的图片 图片保存到本地,老规矩,winhex看一看 拉到最后发现 因为做过ctf新手的密码 所以一看就知道unicode 百度站 ... 
- 79.常用的返回QuerySet对象的方法使用详解: filter, exclude,annotate
			返回新的QuerySet的常用方法: 1.filter: 将满足条件的数据提取出来,返回一个新的QuerySet 以下所使用的模型article,category,定义模型models.py文件中,示 ... 
- HDU 1298 T9 字典树+DFS
			必须要批评下自己了,首先就是这个题目的迟疑不定,去年做字典树的时候就碰到这个题目了,当时没什么好的想法,就暂时搁置了,其实想法应该有很多,只是居然没想到. 同样都是对单词进行建树,并插入可能值,但是拨 ... 
- POJ 1141 经典DP 轨迹打印
			又几天没写博客了,大二的生活实在好忙碌啊,开了五门专业课,每周都是实验啊实验啊实验啊....我说要本月刷够60题,但好像完不成了,也就每天1题的样子.如今写动规还是挺有条理的,包括这道需要打印轨迹,其 ... 
- How to .gitignore all files/folder in a folder, but not the folder itself?
			https://stackoverflow.com/questions/4250063/how-to-gitignore-all-files-folder-in-a-folder-but-not-th ... 
- 1.pycharm使用
			太白金星的文档: https://www.cnblogs.com/jin-xin/articles/9811379.html 下载专业版,找破解码 一个python文件的开头如果有注视,必须是双引号的 ... 
 
			
		