题意:
给一个长度n的字符串,q次操作,每次操作把[l,r]排序,k=0非递增,k=1非递减。
题解:
采用计数排序的复杂度是 O(n∗q) ,无法通过,但有所启示。
可以看出计数就是区间求和,排序就是区间更新,可以用线段树维护。
做法是建立26棵线段树,第i棵树维护第i个字母的位置信息。
计数时,在26棵线段树内分别做一次查询,排序时根据递增还是递减,把相应的区间赋值为相应的字母。
#include
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int N = 1e5+5;
char s[N];
struct SegTree{
int tree[N<<2], lazy[N<<2];
void push_up(int rt){ tree[rt] = tree[rt<<1] + tree[rt<<1|1]; }
void push_down(int rt, int l, int r){
if(lazy[rt] != -1){
int mid = (l+r) >> 1;
tree[rt<<1] = (mid-l+1)*lazy[rt];
tree[rt<<1|1] = (r-mid)*lazy[rt];
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
lazy[rt] = -1;
}
}
void build(int rt, int l, int r, char c){
tree[rt] = 0, lazy[rt] = -1;
if(l == r){
tree[rt] = (s[l] == c);
return;
}
int mid = (l+r) >> 1;
build(lson, c);
build(rson, c);
push_up(rt);
}
void update(int rt, int l, int r, int ql, int qr, int v){
if(ql <= l && qr >= r){
tree[rt] = (r-l+1)*v;
lazy[rt] = v;
return;
}
push_down(rt, l, r);
int mid = (l+r) >> 1;
if(ql <= mid) update(lson, ql, qr, v);
if(qr > mid) update(rson, ql, qr, v);
push_up(rt);
}
int query(int rt, int l, int r, int ql, int qr){
if(ql <= l && qr >= r) return tree[rt];
push_down(rt, l, r);
int res = 0, mid = (l+r) >> 1;
if(ql <= mid) res += query(lson, ql, qr);
if(qr > mid) res += query(rson, ql, qr);
push_up(rt);
return res;
}
void print(int rt, int l, int r, char c){
if(l == r){
if(tree[rt]) s[l] = c;
return;
}
push_down(rt, l, r);
int mid = (l+r) >> 1;
if(tree[rt]) print(lson, c), print(rson,c);
push_up(rt);
}
}tr[30];
void print(int n){
for(int i = 0; i < 26; ++i) tr[i].print(1, 1, n, i+'a');
s[n+1] = 0;
puts(s+1);
}
int main(){
int n, q;
scanf("%d%d", &n, &q);
scanf("%s", s+1);
for(int i = 0; i < 26; ++i) tr[i].build(1, 1, n, 'a'+i);
while(q--){
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
int cot[30] = {0};
for(int i = 0; i < 26; ++i) cot[i] = tr[i].query(1, 1, n, l, r);
for(int i = 0; i < 26; ++i) tr[i].update(1, 1, n, l, r, 0);
if(k == 0){
for(int i = 25; i >= 0; --i){
if(!cot[i]) continue;
tr[i].update(1, 1, n, l, l+cot[i]-1, 1);
l += cot[i];
}
}
else{
for(int i = 0; i <= 25; ++i){
if(!cot[i]) continue;
tr[i].update(1, 1, n, l, l+cot[i]-1, 1);
l += cot[i];
}
}
}
print(n);
}