CodeForces 145 E. Lucky Queries(線段樹)
E. Lucky Queries
Description:
Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal record contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.
Petya brought home string s with the length of n. The string only consists of lucky digits. The digits are numbered from the left to the right starting with 1. Now Petya should execute m queries of the following form:
- switch l r — “switch” digits (i.e. replace them with their opposites) at all positions with indexes from l to r, inclusive: each digit 4 is replaced with 7 and each digit 7 is replaced with 4 (1 ≤ l ≤ r ≤ n);
- count — find and print on the screen the length of the longest non-decreasing subsequence of string s.
Subsequence of a string s is a string that can be obtained from s by removing zero or more of its elements. A string is called non-decreasing if each successive digit is not less than the previous one.
Help Petya process the requests.
Input:
The first line contains two integers n and m (1 ≤ n ≤ 106, 1 ≤ m ≤ 3·105) — the length of the string s and the number of queries correspondingly. The second line contains n lucky digits without spaces — Petya’s initial string. Next m lines contain queries in the form described in the statement.
Output
For each query count print an answer on a single line.
Sample Input:
2 3
47
count
switch 1 2
count
Sample Output:
2
1
Sample Input:
3 5
747
count
switch 1 1
count
switch 1 3
count
Sample Output:
2
3
2
題目連結
有一串只有 和 的數列,需要支援兩種操作
switch l r
將區間 內的 變為 , 變為count
求整個數列的最長不下降子序列長度
看題目範圍很容易想到線段樹做法,其中對線段樹每個節點四個屬性:覆蓋區間內 的數量、 的數量、最長不下降子序列長度、最長不上升子序列長度
其中進行區間更新時把 的數量互換,把最長不下降子序列長度、最長不上升子序列長度互換
而進行更新上傳時時計算最長不下降子序列有三種情況
- 左子樹最長不下降子序列長度+右子樹 的數量
- 左子樹 的數量+右子樹最長不下降子序列長度
- 左子樹 的數量+右子樹 的數量
其中對三種情況取最大值即可,計算最長不上升子序列同理
AC程式碼:
#include <bits/stdc++.h>
using namespace std;
class seg_tree {
public:
typedef int type_t;
struct node {
type_t cnt4, cnt7, rise, fall, lazy;
node(type_t _cnt4 = 0, type_t _cnt7 = 0,
type_t _rise = 1, type_t _fall = 1,
type_t _lazy = 0): cnt4(_cnt4), cnt7(_cnt7),
rise(_rise), fall(_fall),
lazy(_lazy) {}
};
int n;
vector<node> tree;
node Unite(const node &k1, const node &k2) {
node ans;
ans.cnt4 = k1.cnt4 + k2.cnt4;
ans.cnt7 = k1.cnt7 + k2.cnt7;
ans.rise = max(k1.rise + k2.cnt7, max(k1.cnt4 + k2.cnt7, k1.cnt4 + k2.rise));
ans.fall = max(k1.fall + k2.cnt4, max(k1.cnt7 + k2.cnt4, k1.cnt7 + k2.fall));
return ans;
}
void Pull(int o) {
tree[o] = Unite(tree[o << 1], tree[o << 1 | 1]);
}
void Push(int o, int l, int r) {
if (tree[o].lazy != 0) {
swap(tree[o << 1].cnt4, tree[o << 1].cnt7);
swap(tree[o << 1].rise, tree[o << 1].fall);
swap(tree[o << 1 | 1].cnt4, tree[o << 1 | 1].cnt7);
swap(tree[o << 1 | 1].rise, tree[o << 1 | 1].fall);
tree[o << 1].lazy = !tree[o << 1].lazy;
tree[o << 1 | 1].lazy = !tree[o << 1 | 1].lazy;
tree[o].lazy = 0;
}
}
void Build(int o, int l, int r, const vector<type_t> &v) {
if (l == r) {
tree[o].cnt4 = (v[l - 1] == 4);
tree[o].cnt7 = (v[l - 1] == 7);
return;
}
int m = (l + r) >> 1;
Build(o << 1, l, m, v);
Build(o << 1 | 1, m + 1, r, v);
Pull(o);
}
seg_tree(const vector<type_t> &v) {
n = v.size();
tree.resize(n << 2);
Build(1, 1, n, v);
}
void Modify(int o, int l, int r, int ll, int rr) {
if (ll <= l && rr >= r) {
swap(tree[o].cnt4, tree[o].cnt7);
swap(tree[o].rise, tree[o].fall);
tree[o].lazy = !tree[o].lazy;
return;
}
Push(o, l, r);
int m = (l + r) >> 1;
if (ll <= m) Modify(o << 1, l, m, ll, rr);
if (rr > m) Modify(o << 1 | 1, m + 1, r, ll, rr);
Pull(o);
}
void Modify(int ll, int rr) {
Modify(1, 1, n, ll, rr);
}
};
int main() {
ios::sync_with_stdio(false); cin.tie(0);
int n, m; cin >> n >> m;
vector<int> arr(n);
for (int i = 0; i < n; ++i) {
char x; cin >> x;
arr[i] = x - '0';
}
seg_tree sgt(arr);
for (int i = 0, l, r; i < m; ++i) {
string s; cin >> s;
if (s == "count") cout << sgt.tree[1].rise << endl;
else {
cin >> l >> r;
sgt.Modify(l, r);
}
}
return 0;
}
相關文章
- Educational Codeforces Round 19 E. Array Queries
- Codeforces Round #675 (Div. 2) 1442 F - Boring Queries 可持久化線段樹維護 區間乘法持久化
- HDU 4027 Can you answer these queries? (線段樹 區間開方)
- Codeforces Round #373 (Div. 1) C. Sasha and Array 線段樹
- 線~段~樹
- 線段樹
- 線段樹模板
- 線段樹--RMQMQ
- 01 線段樹
- 線段樹 hate it
- 【模版】線段樹
- Codeforces Global Round 19 E. Best PairAI
- ut.cpp 最大線段並減線段交 [線段樹]
- 權值線段樹
- 線段樹筆記筆記
- Segment Tree(線段樹)
- 線段樹入門
- 李超線段樹
- 線段樹進階
- Codeforces 1070C - Cloud Computing 思路+線段樹+貪心 (2018-2019 ICPC, NEERC)Cloud
- 洛谷題單指南-線段樹-P3373 【模板】線段樹 2
- 線段樹擴充套件套件
- 第二課——線段樹
- 線段樹簡單思路
- 深入理解線段樹
- 線段樹(毒瘤)總結
- POJ 3667 Hotel 線段樹
- poj 2667 hotel 線段樹
- 線段樹(超詳解)
- 線段樹 transformation——hdu 4578ORM
- 懶標記線段樹
- 可持久化線段樹持久化
- 線段樹模板總結
- 線段樹 - 多組圖帶你從頭到尾徹底理解線段樹
- 資料結構之樹( 線段樹,字典樹)資料結構
- hdu 1698 線段樹 一段更新染色
- 線段樹也能是 Trie 樹 題解
- 線段樹從零開始