首页 > 其他分享 >12.CF558E A Simple Task 线段树维护字符串区间排序

12.CF558E A Simple Task 线段树维护字符串区间排序

时间:2022-10-28 10:31:09浏览次数:89  
标签:rt lazy Task curr Simple tree CF558E int id


12.CF558E A Simple Task 线段树维护字符串区间排序


要求对于给定的字符串,对给定的区间进行排序

线段树经典应用,维护26棵线段树,实现区间覆盖和查询即可。

洛谷传送门:​​CF558E A Simple Task - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)​

CF传送门:​​E. A Simple Task (codeforces.com)​

题目分析

要求对于给定的字符串,对给定的区间进行排序。

我们维护棵线段树,每颗线段树上记录对应字母所在的位置(叶节点表示有没有,然后维护区间和表示区间字母个数)。对于区间排序,我们只需要取出区间在棵线段树上的信息,然后按照升序或降序覆盖即可。

因为要维护区间覆盖,因此也需要打标记。

Code

#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;

const int N = 2e2 + 10, MOD = 1e9 + 7;

string s;

char ans[N];

namespace SegTree{
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, id, l,
#define rson rs, id, mid + 1,

int tree[N << 2][26], lazy[N << 2][26];

inline void push_up(int rt, int id){ tree[rt][id] = tree[ls][id] + tree[rs][id]; }

inline void push_down(int rt, int id, int m){
if(lazy[rt][id] == -1) return;
lazy[ls][id] = lazy[rs][id] = lazy[rt][id];
tree[ls][id] = lazy[rt][id] * (m - (m >> 1));
tree[rs][id] = lazy[rt][id] * (m >> 1);
lazy[rt][id] = -1;
}
void build(int rt, int id, int l, int r){
lazy[rt][id] = -1, tree[rt][id] = 0;
if(l == r){
tree[rt][id] += (s[l] - 'a' == id);
return;
}
int mid = l + r >> 1;
build(lson), build(rson);
push_up(rt, id);
}

void update(int rt, int id, int l, int r, int L, int R, int val){
if(l >= L && r <= R){
tree[rt][id] = val * (r - l + 1);
lazy[rt][id] = val;
return;
}
push_down(rt, id, r - l + 1);
int mid = l + r >> 1;
if(mid >= L) update(lson, L, R, val);
if(mid < R) update(rson, L, R, val);
push_up(rt, id);
}

int query(int rt, int id, int l, int r, int L, int R){
if(l >= L && r <= R) return tree[rt][id];
push_down(rt, id, r - l + 1);
int mid = l + r >> 1, ans = 0;
if(mid >= L) ans += query(lson, L, R);
if(mid < R) ans += query(rson, L, R);
return ans;
}

void getans(int rt, int id, int l, int r){
if(l == r){
if(tree[rt][id]) ans[l] = (char)('a' + id);
return;
}
push_down(rt, id, r - l + 1);
int mid = l + r >> 1;
getans(lson), getans(rson);
}
}


inline void solve(){
int n, q; cin >> n >> q;
cin >> s, s = '@' + s;
for(int i = 0; i < 26; i++) SegTree::build(1, i, 1, n);
while(q--){
int l, r, k; cin >> l >> r >> k;
vector<int> cnt;
for(int i = 0; i < 26; i++) cnt.emplace_back(SegTree::query(1, i, 1, n, l, r));
if(k){
int curl = l, curr = l;
for(int i = 0; i < 26; i++){
if(!cnt[i]) continue;
curr = curl + cnt[i] - 1;
SegTree::update(1, i, 1, n, l, r, 0);
SegTree::update(1, i, 1, n, curl, curr, 1);
curl = curr + 1;
}
assert(curr == r);
} else {
int curl = l, curr = l;
for(int i = 25; i >= 0; i--){
if(!cnt[i]) continue;
curr = curl + cnt[i] - 1;
SegTree::update(1, i, 1, n, l, r, 0);
SegTree::update(1, i, 1, n, curl, curr, 1);
curl = curr + 1;
}
assert(curr == r);
}
}
for(int i = 0; i < 26; i++) SegTree::getans(1, i, 1, n);
for(int i = 1; i <= n; i++) cout << ans[i];
cout << endl;
}

signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; //cin >> t;
while(t--) solve();
return 0;
}


标签:rt,lazy,Task,curr,Simple,tree,CF558E,int,id
From: https://blog.51cto.com/u_12372287/5803566

相关文章