CF-558E(E. A Simple Task)
生活随笔
收集整理的這篇文章主要介紹了
CF-558E(E. A Simple Task)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CF-558E(E. A Simple Task)
題目鏈接
題意
長度為NNN的串,給qqq次修改每次修改給出一個區間[L,R][L,R][L,R],你需要將區間的字符按照升序或降序排列.輸出qqq次修改的串.
思路
對于每個區間我們可以用計數排序,這樣效率高一點.但如果對于每個詢問我們都O(n)O(n)O(n)遍歷這樣效率有點低,所以可以用線段樹維護每個字符在每個位置的狀態.對于一個詢問先統計統計每個字符出現的數量,然后在對應位置清空,最后將排序之后的插入線段樹中.總的復雜度為O(26?q?log(n))O(26*q*log(n))O(26?q?log(n))
#include <bits/stdc++.h> const int maxn = 1e5 + 5; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; using namespace std; char s[maxn]; struct ac{int T[maxn<<2], lazy[maxn<<2];void pushup(int rt) {T[rt] = T[rt<<1] + T[rt<<1|1];}void pushdown(int rt, int l, int r, int mid) {if (lazy[rt] == -1) return;lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];if (lazy[rt] == 0) {T[rt<<1] = T[rt<<1|1] = 0;}else {T[rt<<1] = mid - l + 1;T[rt<<1|1] = r - mid;}lazy[rt] = -1;}void build(int rt, int l, int r) {if (l == r) {T[l] = 0;lazy[l] = -1;return;}int mid = (l + r) >> 1;build(rt<<1, l, mid);build(rt<<1|1, mid+1, r);pushup(rt);}void update(int rt, int l, int r, int ql, int qr, int d) {if (l > qr || r < ql) return;if (l >= ql && r <= qr) {if (d == 0) lazy[rt] = T[rt] = 0;else {if (lazy[rt] < 1) lazy[rt] = d;else lazy[rt] += d; T[rt] += d * (r - l + 1);}return;}int mid = (l + r) >> 1;pushdown(rt, l, r, mid);update(rt<<1, l, mid, ql, qr, d);update(rt<<1|1, mid+1, r, ql, qr, d);pushup(rt);}int query(int rt, int l, int r, int ql, int qr) {if (l > qr || r < ql) return 0;if (l >= ql && r <= qr) return T[rt];int mid = (l + r) >> 1;pushdown(rt, l, r, mid);int L = query(rt<<1, l, mid, ql, qr);int R = query(rt<<1|1, mid+1, r, ql, qr);return L + R;} }seg[26]; int cnt[30]; int main() {int n, m;scanf("%d %d", &n, &m);scanf("%s", s);for (int i = 0; i < 26; ++i) seg[i].build(1, 1, n);for (int i = 0; i < n; ++i) seg[s[i]-'a'].update(1, 1, n, i+1, i+1, 1);for (int i = 0, l,r,k; i < m; ++i) {scanf("%d %d %d", &l, &r, &k);fill(cnt, cnt+30, 0);for (int j = 0; j < 26; ++j) {cnt[j] += seg[j].query(1, 1, n, l, r);seg[j].update(1, 1, n, l, r, 0);}int pre = 0;if (k == 0) {for (int j = 25; j >= 0; --j) {if (cnt[j] == 0) continue;seg[j].update(1, 1, n, pre+l, pre+cnt[j]+l-1, 1);pre += cnt[j];}}else {for (int j = 0; j < 26; ++j) {if (cnt[j] == 0) continue;seg[j].update(1, 1, n, pre+l, pre+cnt[j]+l-1, 1);pre += cnt[j];}}}for (int i = 1; i <= n; ++i) {for (int j = 0; j < 26; ++j) {if (seg[j].query(1, 1, n, i, i)) {printf("%c", j+'a');goto here;}}here:;}puts("");return 0; }總結
以上是生活随笔為你收集整理的CF-558E(E. A Simple Task)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF-786B(Legacy) 区间最短
- 下一篇: CF - 741(C. Arpa’s o