题目链接: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. Java面试14|Session与Cookie

    1.在分布式环境,管理Session通常使用下面三种方式: (1)Session Replication 方式管理 (即session复制) 将一台机器上的Session数据广播复制到集群中其余机器上 ...

  2. 网络安全实验室 脚本关通关writeup

    [1]key又又找不到了查看源代码.发现key的路径,点击进行了302跳转,抓包,得到key [2]快速口算要2秒内提交答案,果断上python import requests,re s = requ ...

  3. swift -- 静态变量static

    import UIKit class ViewController: UIViewController {     //静态变量  swift中的static静态变量,只能在这里声明,不能在方法中声明 ...

  4. 《C++之那些年踩过的坑(二)》

    C++之那些年踩过的坑(二) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. 今天讲一个小点,虽然小,但如果没有 ...

  5. c#调用aapt查看apk文件信息功能实现

    第一篇随笔就此开始. 1. 起源 思路源自于项目开发过程中.需要确认apk文件版本以验证其功能差异以便于定位问题,于是度娘,得到APK信息查看器(APK-info)这个工具,其版本号为0.2.它能显示 ...

  6. TextView字体大小及颜色设置

    TextView设置文字大小及颜色: 1.1)通过xml配置 <TextView      android:layout_width="match_parent"     a ...

  7. cuda编程学习5——波纹ripple

    /共有DIM×DIM个像素,每个像素对应一个线程dim3 blocks(DIM/16,DIM/16);//2维dim3 threads(16,16);//2维kernel<<<blo ...

  8. Alamofire源码解读系列(八)之安全策略(ServerTrustPolicy)

    本篇主要讲解Alamofire中安全验证代码 前言 作为开发人员,理解HTTPS的原理和应用算是一项基本技能.HTTPS目前来说是非常安全的,但仍然有大量的公司还在使用HTTP.其实HTTPS也并不是 ...

  9. (Facebook开源项目)Fresco:一个新的Android图像处理类库

    在Facebook的Android客户端上快速高效的显示图片是非常重要的.然而多年来,我们遇到了很多如何高效存储图片的问题.图片太大,而设备太小.一个像素点就占据了4个字节数据(分别代表R G B和a ...

  10. oracle查询每个表所占的空间

    查看当前用户的每个表所占的空间大小: select segment_name,sum(bytes)/1024/1024 size_M from user_extents group by segmen ...