题目链接:http://codeforces.com/problemset/problem/558/E

给一个字符串,每次对一个区间内的子串进行升序或者降序的排列,问最后字符串什么样子。

对于字符串排序,计数排序是比一般的排序要快的,但是仍然不能解决本问题。

建立26个线段树,用于统计某个字符在某个区间的情况。

那么如果对【L,R】排序,则先统计所有字符在其中的情况,并且清空该区间,根据每个字符的数量,从a到z去填充应该在的小区间。

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <numeric>
#include <cassert> using namespace std; const int N=1e5+; char s[N]; struct SegmentTree {
#define M N*4
int val[M];
int flag[M];
void up(int rt) {
val[rt]=val[rt<<]+val[rt<<|];
}
void build(int l,int r,int rt) {
if (l==r) {
val[rt]=;
flag[rt]=-;
return;
}
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
up(rt);
}
void down(int rt,int m=) {
if (flag[rt]!=-) {
flag[rt<<]=flag[rt];
flag[rt<<|]=flag[rt];
if (flag[rt]==){
val[rt<<]=m-(m>>);
val[rt<<|]=(m>>);
}
else {
val[rt<<]=;
val[rt<<|]=;
}
flag[rt]=-;
}
}
void update(int p,int c,int l,int r,int rt) {
if (l==r) {
val[rt]=c;
return;
}
down(rt,r-l+);
int m=(l+r)>>;
if (p<=m)
update(p,c,l,m,rt<<);
else
update(p,c,m+,r,rt<<|);
up(rt);
}
void update(int L,int R,bool c,int l,int r,int rt) {
if (L<=l&&r<=R) {
val[rt]=c?(r-l+):;
flag[rt]=c;
return;
}
down(rt,r-l+);
int m=(l+r)>>;
if (L<=m) update(L,R,c,l,m,rt<<);
if (R>m) update(L,R,c,m+,r,rt<<|);
up(rt);
}
int query(int p,int l,int r,int rt) {
if (l==r) {
return val[rt];
}
down(rt,r-l+);
int m=(l+r>>);
if (p<=m) return query(p,l,m,rt<<);
else return query(p,m+,r,rt<<|);
}
int query(int L,int R,int l,int r,int rt) {
if (L<=l&&r<=R) {
return val[rt];
}
down(rt,r-l+);
int m=(l+r)>>;
int ret=;
if (L<=m) ret+=query(L,R,l,m,rt<<);
if (R>m) ret+=query(L,R,m+,r,rt<<|);
return ret;
}
#undef M
}seg[]; int main() {
int n,q;
scanf("%d %d",&n,&q);
scanf("%s",s+);
for (int i=;i<;i++)
seg[i].build(,n,);
for (int i=;i<=n;i++) {
int p=s[i]-'a';
seg[p].update(i,,,n,);
//cout<<p<<" xxx"<<endl;
}
while (q--) {
int l,r,t;
scanf("%d %d %d",&l,&r,&t);
int cnt[];
for (int i=;i<;i++) {
cnt[i]=seg[i].query(l,r,,n,);
if (cnt[i]>){
seg[i].update(l,r,,,n,);
}
}
if (t==) {
for (int i=;i<;l+=cnt[i++]){
if (cnt[i]==) continue;
seg[i].update(l,l+cnt[i]-,,,n,);
}
}
else {
for (int i=;i>=;l+=cnt[i--]){
if (cnt[i]==) continue;
seg[i].update(l,l+cnt[i]-,,,n,);
}
}
}
for (int i=;i<=n;i++) {
for (int j=;j<;j++){
if (seg[j].query(i,,n,)) {
s[i]='a'+j;
break;
}
}
}
s[n+]=;
printf("%s\n",s+);
return ;
}

CF #312 E. A Simple Task 线段树的更多相关文章

  1. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树

    E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...

  2. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序

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

  3. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树 延时标记

    E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input ...

  4. CodeForces 588E A Simple Task(线段树)

    This task is very simple. Given a string S of length n and q queries each query is on the format i j ...

  5. Codeforces 588E. A Simple Task (线段树+计数排序思想)

    题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...

  6. CF#312 558e A Simple Task

    ~~~题面~~~ 题解: 观察到字母只有26个,因此考虑对这26个字母分别维护,每个线段树维护一个字母,如果一个线段树的某个叶节点有值,表示当前叶节点所在位置的字母是现在这个线段树代表的字母. 那么对 ...

  7. CF558E A simple task 线段树

    这道题好猥琐啊啊啊啊啊啊 写了一个上午啊啊啊啊 没有在update里写pushup啊啊啊啊 题目大意: 给你一个字符串s,有q个操作 l r 1 :把sl..rsl..r按升序排序 l r 0 :把s ...

  8. codeforces 558E A Simple Task 线段树

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

  9. [Codeforces558E]A Simple Task 线段树

    链接 题意:给定一个长度不超过 \(10^5\) 的字符串(小写英文字母),和不超过5000个操作. 每个操作 L R K 表示给区间[L,R]的字符串排序,K=1为升序,K=0为降序. 最后输出最终 ...

随机推荐

  1. Swift应用案例 1.无限轮播

      从今天开始,我学习的重点开始转向Swift,并且会分享一些自己学习的心得体会,今天给大家带来的的是无限轮播.广告页的无限轮播是非常常见的一个功能,大多数APP都有,大多数程序员也都实现过,今天我们 ...

  2. 移动端利用rem实现自适应布局

    好久没有写博客了,刚好说说最近遇到的移动端布局问题吧. 本来一直是觉得我的页面布局能力还是不错的,当然,是相对于较基础的来说还是不错的.不过,自己写的案例终归是跟实际开发有区别的,自己写案例的是觉得这 ...

  3. [BNUZOJ1261][ACM][2016北理校赛]方块消除(栈,字符串)

    玩过方块消除游戏吗?现在规定当有两个或两个以上相邻且颜色相同的方块在一起的时候,它们就会产生消除反应.当存在多个消除反应同时产生时,最下的反应先执行.现在只给你其中一列,求最后剩下的方块结果. 输入要 ...

  4. javascript 随机显示指定内容

    今天碰到一个需求,一个页面显示赞助厂商的信息,但是厂商要求排序要随机排,因为是个静态页面不是读取数据库的,所以打算用js来控制 var arr = new Array('张三', '李四', '王五' ...

  5. ConfigParser-- 读取写入配置文件

    基础读取配置文件   -read(filename)               直接读取文件内容 -sections()                      得到所有的section,并以列表 ...

  6. ehcache 使用笔记

    要想使用 java 的本地缓存,可以考虑用 ehcache,或者 guava. guava 更高端一点,可以自动定时刷新.我选择了 ehcache. 在 spring 中是集成了 ehcache 的. ...

  7. CCS内存数据转成图片

    在嵌入式DSP图像处理开发过程中,经常需要将DSP内存中的图像数据保存下来,作为数据集.CCS5.4或者CCS3.3都只支持保存内存原始数据而不支持将内存数据直接存储为一张图片,为了能将CCS保存的. ...

  8. WP8.1小梦词典开发2:百度翻译API使用

    原文出自:http://www.bcmeng.com/api2/ 小梦昨天和大家分享了WP8.1金山词霸API使用方法,今天继续分享windows phone 8.1中百度翻译API的使用方法.和昨天 ...

  9. download 下载文件 IE兼容性处理

    根据CANIUSE(http://caniuse.com/#search=download)download兼容性如下图所示: 如上图所示,IE浏览器是不支持的. 1.测试代码: <!docty ...

  10. 通用数据库帮助类DBHelper(含log日志信息实时记录)

    项目需要,需要一个通用的数据库操作类,增删改查.事务.存储过程.日志记录都要有,于是在已有的帮助类上做了一些改进,并将log4j的.NET版--log4net嵌入其中记录sql的执行环境和状态. 用起 ...