14123: 【原4123】String
题目
题目描述
author: Ca. 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4123
Description
给定一个由小写字母组成的字符串s。有m次操作,每次操作给定3个参数(l, r, x)。 如果x=1,将s[l]~s[r]升序排序; 如果x=0,将s[l]~s[r]降序排序。 现在需要你求出最终序列。
Input Format
第一行两个整数n, m。 第二行一个字符串s。 接下来m行每行三个由空格隔开的整数x, l, r。
Output Format
一行一个字符串表示最终序列。
Sample Input
5 2
cabcd
1 3 1
3 5 0
Sample Output
abdcc
Data Range
对于 40%的数据,n,m<=1000。 对于 100%的数据,n,m<=100000。
FineArtz's solution
/* String */
q4x3's solution
/**
* 线段树
* 以后再说
**/
#include <iostream>
#include <stdio.h>
using namespace std;
void build(int rt) {
}
zqy2018's solution
/*
See the solution at https://github.com/zqy1018/sjtu_oj_solutions/blob/master/solutions/sjtu4123.md
*/
#include <bits/stdc++.h>
#define INF 2000000000
using namespace std;
typedef long long ll;
int read(){
int f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
return f * x;
}
int n, m, ql[100005], qr[100005], qx[100005];
int seg[263000] = {0}, tag[263000] = {0};
int siz, _a, _b, _v;
char s[100005], ans[100005] = {0};
void pushdown(int id, int len){
if (tag[id] != 0){
if (tag[id] == 1)
seg[id << 1] = seg[id << 1 | 1] = 0;
else
seg[id << 1] = seg[id << 1 | 1] = len;
tag[id << 1] = tag[id << 1 | 1] = tag[id];
tag[id] = 0;
}
}
void update(int id, int l, int r){
if (r < _a || l > _b) return ;
if (l >= _a && r <= _b){
if (_v == 1) seg[id] = 0;
else seg[id] = (r - l + 1);
tag[id] = _v;
return ;
}
int len = (r - l + 1) >> 1;
pushdown(id, len);
update(id << 1, l, l + len - 1);
update(id << 1 | 1, l + len, r);
seg[id] = seg[id << 1] + seg[id << 1 | 1];
}
int query(int id, int l, int r){
if (r < _a || l > _b) return 0;
if (l >= _a && r <= _b) return seg[id];
int len = (r - l + 1) >> 1;
pushdown(id, len);
return query(id << 1, l, l + len - 1) + query(id << 1 | 1, l + len, r);
}
void dfs(int id, int len){
pushdown(id, len);
if ((id << 1) >= siz) return ;
dfs(id << 1, len >> 1);
dfs(id << 1 | 1, len >> 1);
}
void init(){
n = read(), m = read();
scanf("%s", s);
for (int i = 1; i <= m; ++i)
ql[i] = read(), qr[i] = read(), qx[i] = read();
for (siz = 1; siz < n; siz <<= 1);
}
void solve(){
if (n == 1) {
printf("%s\n", s);
return ;
}
for (int j = 0; j < 26; ++j){
for (int i = 0; i < n; ++i){
if (s[i] - 'a' <= j)
seg[i + siz] = 1;
else seg[i + siz] = 0;
tag[i + siz] = 0;
}
for (int i = siz - 1; i >= 1; --i)
seg[i] = seg[i << 1] + seg[i << 1 | 1],
tag[i] = 0;
for (int i = 1; i <= m; ++i){
_a = ql[i], _b = qr[i];
int sm = query(1, 1, siz);
if (sm == _b - _a + 1) continue;
if (qx[i] == 1)
_v = 2, _b = _a + sm - 1, update(1, 1, siz),
_v = 1, _a = _b + 1, _b = qr[i], update(1, 1, siz);
else
_v = 2, _a = _b - sm + 1, update(1, 1, siz),
_v = 1, _b = _a - 1, _a = ql[i], update(1, 1, siz);
}
dfs(1, (siz >> 1));
for (int i = 0; i < n; ++i)
if (seg[i + siz] && !ans[i])
ans[i] = j + 'a';
}
ans[n] = '\0';
printf("%s\n", ans);
}
int main(){
init();
solve();
return 0;
}