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(计数排序+线段树优化)的更多相关文章

  1. Codeforces 558E A Simple Task (计数排序&&线段树优化)

    题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...

  2. CodeForces 558E(计数排序+线段树优化)

    题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...

  3. 计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

    E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作, ...

  4. Nowcoder Hash Function ( 拓扑排序 && 线段树优化建图 )

    题目链接 题意 : 给出一个哈希表.其避免冲突的方法是线性探测再散列.现在问你给出的哈希表是否合法.如果合法则输出所有元素插入的顺序.如果有多解则输出字典序最小的那一个.如果不合法则输出 -1 分析 ...

  5. Codeforces 1603D - Artistic Partition(莫反+线段树优化 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 学 whk 时比较无聊开了道题做做发现是道神题( 介绍一种不太一样的做法,不观察出决策单调性也可以做. 首先一个很 trivial 的 o ...

  6. Codeforces.1045A.Last chance(最大流ISAP 线段树优化建图)

    题目链接 \(Description\) 你需要用给定的\(n\)个武器摧毁\(m\)架飞船中的某一些.每架飞船需要被摧毁恰好一次. 武器共三种:1.可以在给定的集合中摧毁一架飞船:2.可以摧毁区间\ ...

  7. Codeforces 558E A Simple Task(权值线段树)

    题目链接  A Simple Task 题意  给出一个小写字母序列和若干操作.每个操作为对给定区间进行升序排序或降序排序. 考虑权值线段树. 建立26棵权值线段树.每次操作的时候先把26棵线段树上的 ...

  8. codeforces 558E A Simple Task 线段树

    题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...

  9. Codeforces 558E A Simple Task

    题意:给定一个字符串,以及m次操作,每次操作对字符串的一个子区间进行升序或降序排序,求m次操作后的串 考虑桶排,发现线段树可以模拟桶排的过程,所以对26个字母分别建立线段树即可 #include< ...

随机推荐

  1. java基础——既然有了字节流,为什么还要有字符流呢?

    不管是文件读写还是网络发送接收,信息的最小存储单元都是字节,那为什么I/O流操作要分字节流操作和字符流操作呢? 字符流是由JVM将字节转换得到的,所以这个过程还是非常耗时的,同样假如我们不知道编码方式 ...

  2. Python 使用print实现进度

    import time print("0%",end='') time.sleep(2) print("\r1%",end='') time.sleep(2) ...

  3. trove database功能总结

    我曾经以为trove只负责数据库(datastore)的部署,最近才发现trove可以进行数据库(database)的创建. 首先是列出某个实例上(instance)数据库(datastrore)上的 ...

  4. VMware-Workstation-Full-12.5.9

    https://download3.vmware.com/software/wkst/file/VMware-Workstation-Full-12.5.9-7535481.x86_64.bundle ...

  5. 1-4 无监督学习(Unsupervised Learning)

    无监督学习定义: [无监督学习]中没有任何的标签或者是有相同的标签或者就是没标签.所以我们已知数据集,却不知如何处理,也未告知每个数据点是什么.别的都不知道,就是一个数据集.你能从数据中找到某种结构吗 ...

  6. python 爬虫下载英语听力新闻(npr news)为mp3格式

    想通过听实时新闻来提高英语听力,学了那么多年的英语,不能落下啊,不然白费背了那么多年的单词. npr news是美国国家公共电台,发音纯正,音频每日更新,以美国为主,世界新闻为辅,比如最近我国武汉发生 ...

  7. 注册网站 captcha reCHAPTCHA 错误

    原因 出现这个错误,是因为注册和提交时候,没有正确输出验证码导致的.网站可能会为了防止恶意注册,而使用验证码.如果验证码没有被正确加载或验证,就会出现相关错误. 解决方案 如果是访问类似kaggle, ...

  8. awk中传参方式

    结合编辑数据文件的shell脚本学习awk传参方式,该脚本功能: a.取VIDEOUSR_11082017_0102_ONLINE_STASTIC.dat文件中第87个字段的低8位: b.将每行数据的 ...

  9. App的布局管理

    今天学习了布局管理器,格局自己的学习内容和课程,我主要学习了两种管理布局方式 一:LinearLayout线性布局 线性布局是指布局里面的内容成线性排列,有两种排列方式,横向排列和纵向排列,而排列方式 ...

  10. h5-FileReader对象的使用

    <!--FileReader对象的使用--> <!--需要及时预览 及时:当用户选择完图片之后就立即进行预览处理--onchange事件 预览:通过文件读取对象的readAsData ...