这道题对字符进行排序要用counting sort, 其中统计每个字符的个数要用到线段树。所以需要为26个字母建26个线段树,统计某个字母在某个区间的数目。线段树的操作为区间更新和区间求和。
#include <bits/stdc++.h>
#define maxn 100005
#define INF 1e9
using namespace std;
typedef long long ll;
int sum[26][maxn<<2], add[26][maxn<<2];
void Pushdown(int *p1, int *p2, int n, int m){
if(p2[n] != -1){
p1[n<<1] = p2[n] * (m - (m >> 1));
p1[n<<1|1] = p2[n] * (m >> 1);
p2[n<<1] = p2[n<<1|1] = p2[n];
p2[n] = -1;
}
}
void Update(int *p1, int *p2, int n, int L, int R, int l, int r, int d){
if(l == L && r == R){
p2[n] = d;
p1[n] = (r - l + 1) * d;
return ;
}
Pushdown(p1, p2, n, R - L + 1);
int mid = (L + R) >> 1;
if(r <= mid)
Update(p1, p2, n<<1, L, mid, l, r, d);
else if(l > mid)
Update(p1, p2, n<<1|1, mid+1, R, l, r, d);
else{
Update(p1, p2, n<<1, L, mid, l, mid, d);
Update(p1, p2, n<<1|1, mid+1, R, mid+1, r, d);
}
p1[n] = p1[n<<1] + p1[n<<1|1];
}
void Query(int *p1, int *p2, int n, int L, int R, int l, int r, int &s){
if(l == L && R == r){
s += p1[n];
return ;
}
Pushdown(p1, p2, n, R - L + 1);
int mid = (L + R) >> 1;
if(r <= mid)
Query(p1, p2, n<<1, L, mid, l, r, s);
else if(l > mid)
Query(p1, p2, n<<1|1, mid+1, R, l, r, s);
else{
Query(p1, p2, n<<1, L, mid, l, mid, s);
Query(p1, p2, n<<1|1, mid+1, R, mid+1, r, s);
}
}
int main(){
// freopen("in.txt", "r", stdin);
int n, q;
while(scanf("%d%d ", &n, &q) == 2){
char ch;
memset(sum, 0, sizeof(sum));
memset(add, -1, sizeof(add));
for(int i = 1; i <= n; i++){
scanf("%c ", &ch);
Update(sum[ch-'a'], add[ch-'a'], 1, 1, n, i, i, 1);
}
int a, b, c;
for(int i = 0; i < q; i++){
int cnt;
scanf("%d%d%d", &a, &b, &c);
if(c == 1)
cnt = a;
else
cnt = b;
for(int j = 0; j < 26; j++){
int s = 0;
Query(sum[j], add[j], 1, 1, n, a, b, s);
if(s){
Update(sum[j], add[j], 1, 1, n, a, b, 0);
if(c == 1){
Update(sum[j], add[j], 1, 1, n, cnt, cnt+s-1, 1);
cnt += s;
}
else{
Update(sum[j], add[j], 1, 1, n, cnt-s+1, cnt, 1);
cnt -= s;
}
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 0; j < 26; j++){
int s = 0;
Query(sum[j], add[j], 1, 1, n, i, i, s);
if(s){
printf("%c", 'a'+j);
break;
}
}
}
}
return 0;
}