Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序
题目链接:
http://codeforces.com/problemset/problem/558/E
E. A Simple Task
time limit per test5 secondsmemory limit per test512 megabytes
#### 问题描述
> This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.
>
> Output the final string after applying the queries.
输入
The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively.
Next line contains a string S itself. It contains only lowercase English letters.
Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, ).
输出
Output one line, the string S after applying the queries.
样例输入
10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1
样例输出
cbcaaaabdd
题意
给你一个长度为n的字符串(只有小写字母),m个更新操作(l,r,type)要么对区间里面的字符串升序排,要么降序排,问m个更新之后最后的字符串是什么
题解
首先,只有26个字母,可以考虑计数排序,其次,当然是要用线段树来维护了,可以开26颗线段树,支持区间更新,区间查询。
对于更新区间先查询一下各个字母多少个,然后再按排完序的结果,26个字母(对应26颗线段树)全部干一发区间更新。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=1e5+10;
int sumv[26][maxn<<2],setv[26][maxn<<2];
int n,m;
char str[maxn];
void maintain(int id,int o) {
sumv[id][o]=sumv[id][lson]+sumv[id][rson];
}
void pushdown(int id,int o,int l,int r) {
if(setv[id][o]<0) return;
sumv[id][lson]=(mid-l+1)*setv[id][o];
sumv[id][rson]=(r-mid)*setv[id][o];
setv[id][lson]=setv[id][rson]=setv[id][o];
setv[id][o]=-1;
}
void build(int id,int o,int l,int r) {
if(l==r) {
int idx=str[l]-'a';
if(id==idx) sumv[id][o]=1;
else sumv[id][o]=0;
} else {
build(id,lson,l,mid);
build(id,rson,mid+1,r);
maintain(id,o);
}
}
int ul,ur,uv;
void update(int id,int o,int l,int r) {
if(ul<=l&&r<=ur) {
sumv[id][o]=(r-l+1)*uv;
setv[id][o]=uv;
} else {
pushdown(id,o,l,r);
if(ul<=mid) update(id,lson,l,mid);
if(ur>mid) update(id,rson,mid+1,r);
maintain(id,o);
}
}
int ql,qr,qv;
void query(int id,int o,int l,int r) {
if(ql<=l&&r<=qr) {
qv+=sumv[id][o];
} else {
pushdown(id,o,l,r);
if(ql<=mid) query(id,lson,l,mid);
if(qr>mid) query(id,rson,mid+1,r);
maintain(id,o);
}
}
void init() {
clr(sumv,0);
clr(setv,-1);
}
int main() {
init();
scf("%d%d",&n,&m);
scf("%s",str+1);
rep(i,0,26) build(i,1,1,n);
rep(i,0,m) {
int l,r,type;
scf("%d%d%d",&l,&r,&type);
int lef=l;
if(type==1) {
rep(i,0,26) {
ql=l,qr=r,qv=0;
query(i,1,1,n);
ul=l,ur=r,uv=0;
update(i,1,1,n);
ul=lef,ur=lef+qv-1,uv=1;
if(ul<=ur) update(i,1,1,n);
lef+=qv;
}
} else {
for(int i=25; i>=0; i--) {
ql=l,qr=r,qv=0;
query(i,1,1,n);
ul=l,ur=r,uv=0;
update(i,1,1,n);
ul=lef,ur=lef+qv-1,uv=1;
if(ul<=ur){
// prf("(%d,%d),id:%d\n",ul,ur,i);
update(i,1,1,n);
}
lef+=qv;
}
}
}
for(int i=1;i<=n;i++){
rep(j,0,26){
ql=i,qr=i,qv=0;
query(j,1,1,n);
if(qv>0){
prf("%c",'a'+j);
break;
}
}
}
puts("");
return 0;
}
//end-----------------------------------------------------------------------
/*
10 1
abacdabcda
7 10 0
*/
Notes
以后需要建多颗线段树的时候最好把它们所有的操作都独立开,不要放在一起!因为放在一起反而有可能变麻烦。
Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序的更多相关文章
- 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 ...
- 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 ...
- Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...
- Codeforces Round #312 (Div. 2) E. A Simple Task
题目大意就是给一个字符串,然后多个操作,每次操作可以把每一段区间的字符进行升序或者降序排序,问最终的字符串是多少. 一开始只考虑字符串中字符'a'的情况,假设操作区间[L,R]中有x个'a',那么一次 ...
- Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树
C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树
题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线
D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)
题目链接:http://codeforces.com/contest/610/problem/D 就是给你宽度为1的n个线段,然你求总共有多少单位的长度. 相当于用线段树求面积并,只不过宽为1,注意y ...
- Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
随机推荐
- [Doctrine Migrations] 数据库迁移组件的深入解析四:集成diff方式迁移组件
场景及优势 熟悉Symfony框架之后,深刻感受到框架集成的ORM组件Doctrine2的强大之处,其中附带的数据迁移也十分方便.Doctrine2是使用Doctrine DBAL组件把代码里面的表结 ...
- [教学] Delphi IDE 文件搜寻功能
Delphi IDE 提供了一个方便的文件搜寻功能,操作如下: 点 Search 选单内的 Find in Files... 例如我们想搜寻 JFile 需要引用那一个源码,可输入如下: 输入关键字: ...
- 20155301 《Java程序设计》实验五网络编程与安全
20155301 <Java程序设计>实验五网络编程与安全 实验内容 实验1: 两人一组结对编程:参考http://www.cnblogs.com/rocedu/p/6766748.htm ...
- MyOD课堂实践(5月31日)20155318
MyOD课堂实践(5月31日)20155318 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 (码云链接) 代码 import java.io ...
- linux下order by 报出ORDER BY clause is not in SELECT list
一.问题: 在程序执行查询的时候,order by 不能找到要排序的列 二.解决: 在linux环境下,程序之前连接其他库可以正常运行,但是换了一个库后数据就不能正常的显示了,查看后台报出排序列找不到 ...
- Dlib简介及在windows7 vs2013编译过程
Dlib是一个C++库,包含了许多机器学习算法.它是跨平台的,可以应用在Windows.Linux.Mac.embedded devices.mobile phones等.它的License是Boos ...
- 使用Python进行分布式系统协调 (ZooKeeper/Consul/etcd)
来源:naughty 链接:my.oschina.net/taogang/blog/410864 笔者之前的博文提到过,随着大数据时代的到来,分布式是解决大数据问题的一个主要手段,随着越来越多的分布式 ...
- RHCSA-day1
1. 破解密码 开机 e 进入编辑模式 linux16 /boot/.............................en_US.UTF_8 这行末尾插入 rd.break (空格) ctrl ...
- 【Loj10222】佳佳的Fibonacci
题面 题解 可以发现\(T(n)\)无法用递推式表示. 于是我们做如下变形: \[ T(n) = \sum _ {i = 1} ^ n i \times f_i \\ S(n) = \sum _ {i ...
- 【LG4185】[USACO18JAN]MooTube
[LG4185][USACO18JAN]MooTube 题面 洛谷 题解 先将所有操作和询问离线 然后按照边权从大到小将操作和询问排序 利用\(two\;pointers\),每次扫到一个询问,将边权 ...