传送门:A Simple Task
题意: 给定一个长度不超过10^5的字符串(小写英文字母),和不超过50000个操作。
每个操作 L R K 表示给区间[L,R]的字符串排序,K=1为升序,K=0为降序。
最后输出最终的字符串。
思路: 26棵线段树维护26个字母
#include<bits/stdc++.h>
using namespace std;
#define lc i << 1
#define rc i << 1 | 1
#define int long long
#define mem(a, b) memset(a, b, sizeof(a))
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N = 1e5 + 5;
struct node{
int l, r, w[30], f[30];
}e[N << 2];
struct point{
int w[30];
}p;
int n, m;
int a[N];
char s[N];
void pushdown(int i){
if(e[i].l == e[i].r) return;
for(int j = 1; j <= 26; j ++){
if(e[i].f[j]){
for(int k = 1; k <= 26; k ++){
e[lc].w[k] = e[lc].f[k] = 0;
e[rc].w[k] = e[rc].f[k] = 0;
}
e[lc].f[j] = 1;
e[rc].f[j] = 1;
e[lc].w[j] = e[lc].r - e[lc].l + 1;
e[rc].w[j] = e[rc].r - e[rc].l + 1;
e[i].f[j] = 0;
break;
}
}
}
void pushup(int i){
for(int j = 1; j <= 26; j ++)
e[i].w[j] = e[lc].w[j] + e[rc].w[j];
}
void build(int i, int l, int r){
e[i].l = l; e[i].r = r;
if(l == r){
e[i].w[a[l]] = 1;
return;
}
int mid = l + r >> 1;
build(lc, l, mid); build(rc, mid + 1, r);
pushup(i);
}
void modify(int i, int l, int r, int x){
if(e[i].l > r || e[i].r < l) return;
if(l <= e[i].l && e[i].r <= r){
for(int j = 1; j <= 26; j ++){
e[i].w[j] = e[i].f[j] = 0;
}
e[i].f[x] = 1;
e[i].w[x] = e[i].r - e[i].l + 1;
return;
}
pushdown(i);
int mid = e[i].l + e[i].r >> 1;
if(l <= mid) modify(lc, l, r, x);
if(r > mid) modify(rc, l, r, x);
pushup(i);
}
point add(point x, point y){
auto t = p;
for(int i = 1; i <= 26; i ++)
t.w[i] = x.w[i] + y.w[i];
return t;
}
point query(int i, int l, int r){
if(e[i].r < l || e[i].l > r) return p;
else if(l <= e[i].l && e[i].r <= r){
point t = p;
for(int j = 1; j <= 26; j ++)
t.w[j] = e[i].w[j];
return t;
}
pushdown(i);
int mid = e[i].l + e[i].r >> 1;
return add(query(lc, l, r), query(rc, l, r));
}
void eval(int i){
pushdown(i);
if(e[i].l == e[i].r) return;
eval(lc); eval(rc);
}
void print(int rt){
if(e[rt].l == e[rt].r){
for(int i=1;i <= 26;i++){
if(e[rt].w[i]){
printf("%c",i-1+'a');
return;
}
}
}
print(rt << 1);
print(rt << 1 | 1);
}
signed main(){
cin >> n >> m;
cin >> s + 1;
for(int i = 1; s[i]; i ++)
a[i] = s[i] - 'a' + 1;
build(1, 1, n);
//print(1);
while(m --){
int l, r, k;
cin >> l >> r >> k;
auto t = query(1, l, r);
if(k == 1){
for(int i = 1; i <= 26; i ++){
modify(1, l, l + t.w[i] - 1, i);
l += t.w[i];
}
}
else{
for(int i = 26; i >= 1; i --){
modify(1, l, l + t.w[i] - 1, i);
l += t.w[i];
}
}
}
eval(1);
put(1);
puts("");
}