fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #ifdef LOCAL
  5. #include "cp/debug.h"
  6. #else
  7. #define debug(...)
  8. #endif
  9.  
  10.  
  11. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  12.  
  13. const int MOD = (int) 1e9 + 7;
  14. const int INF = 0x3f3f3f3f;
  15.  
  16. struct Info {
  17. int pref[2]{}, suff[2]{};
  18. int l[2]{}; // l[i] = longest `i` subarray
  19. int cnt[2]{}; // the number of ones
  20. int range{};
  21. Info() {}
  22. Info (int val) {
  23. pref[val] = 1;
  24. suff[val] = 1;
  25. l[val] = 1;
  26. cnt[val] = 1;
  27. range = 1;
  28. }
  29. void set(int val) {
  30. pref[val] = range;
  31. pref[!val] = 0;
  32. suff[val] = range;
  33. suff[!val] = 0;
  34. l[val] = range;
  35. l[!val] = 0;
  36. cnt[val] = range;
  37. cnt[!val] = 0;
  38. }
  39. void reverse() {
  40. swap(pref[0], pref[1]);
  41. swap(suff[0], suff[1]);
  42. swap(l[0], l[1]);
  43. swap(cnt[0], cnt[1]);
  44. assert(cnt[0] + cnt[1] == range);
  45. }
  46. };
  47.  
  48. Info join(const Info &lhs, const Info &rhs) {
  49. Info ans{};
  50. for (int t = 0; t <= 1; ++t) {
  51. ans.pref[t] = (lhs.pref[t] == lhs.range ? lhs.range + rhs.pref[t] : lhs.pref[t]);
  52. ans.suff[t] = (rhs.suff[t] == rhs.range ? rhs.range + lhs.suff[t] : rhs.suff[t]);
  53. ans.l[t] = max({lhs.l[t], rhs.l[t], lhs.suff[t] + rhs.pref[t]});
  54. ans.cnt[t] = lhs.cnt[t] + rhs.cnt[t];
  55. }
  56. ans.range = lhs.range + rhs.range;
  57. return ans;
  58. }
  59.  
  60. struct SegmentTree {
  61. int n;
  62. vector<Info> tree;
  63. vector<bool> lazy_rev;
  64. vector<int> lazy_set;
  65. SegmentTree() {}
  66. SegmentTree(int _n): n(1) {
  67. while (n < _n) n *= 2;
  68. tree.resize(n * 2);
  69. lazy_rev.resize(n * 2);
  70. lazy_set.resize(n * 2, -1);
  71. }
  72. void pull(int x) {
  73. tree[x] = join(tree[x * 2], tree[x * 2 + 1]);
  74. }
  75. void build(int x, int l, int r, vector<int> &arr) {
  76. if (l == r) {
  77. tree[x] = Info(arr[l]);
  78. return;
  79. }
  80. int mid = (l + r) >> 1;
  81. build(x * 2, l, mid, arr);
  82. build(x * 2 + 1, mid + 1, r, arr);
  83. pull(x);
  84. }
  85. void push(int x) {
  86. if (!lazy_rev[x] && lazy_set[x] == -1) return;
  87. if (lazy_set[x] != -1) {
  88. int val = lazy_set[x];
  89. lazy_set[x] = -1;
  90. for (int child : {x * 2, x * 2 + 1}) {
  91. lazy_set[child] = val;
  92. lazy_rev[child] = false;
  93. tree[child].set(val);
  94. }
  95. }
  96. if (lazy_rev[x]) {
  97. lazy_rev[x] = !lazy_rev[x];
  98. for (int child : {x * 2, x * 2 + 1}) {
  99. lazy_rev[child] = !lazy_rev[child];
  100. tree[child].reverse();
  101. }
  102. }
  103. }
  104. void set(int x, int l, int r, int u, int v, int val) {
  105. // set all value in range [u..v] to `val`
  106. if (r < u || l > v) return;
  107. if (u <= l && r <= v) {
  108. tree[x].set(val);
  109. lazy_rev[x] = false;
  110. lazy_set[x] = val;
  111. return;
  112. }
  113. int mid = (l + r) >> 1;
  114. push(x);
  115. set(x * 2, l, mid, u, v, val);
  116. set(x * 2 + 1, mid + 1, r, u, v, val);
  117. pull(x);
  118. }
  119. void reverse(int x, int l, int r, int u, int v) {
  120. // reverse all value in range [u..v]
  121. if (r < u || l > v) return;
  122. if (u <= l && r <= v) {
  123. tree[x].reverse();
  124. lazy_rev[x] = !lazy_rev[x];
  125. return;
  126. }
  127. int mid = (l + r) >> 1;
  128. push(x);
  129. reverse(x * 2, l, mid, u, v);
  130. reverse(x * 2 + 1, mid + 1, r, u, v);
  131. pull(x);
  132. }
  133. Info query(int x, int l, int r, int u, int v) {
  134. if (r < u || l > v) return Info{};
  135. if (u <= l && r <= v) return tree[x];
  136. int mid = (l + r) >> 1;
  137. push(x);
  138. Info left = query(x * 2, l, mid, u, v);
  139. Info right = query(x * 2 + 1, mid + 1, r, u, v);
  140. return join(left, right);
  141. }
  142. };
  143.  
  144. int main() {
  145. ios::sync_with_stdio(false); cin.tie(nullptr);
  146. SegmentTree tree;
  147. int n, q;
  148. cin >> n >> q;
  149. vector<int> arr(n);
  150. for (int i = 0; i < n; ++i) {
  151. cin >> arr[i];
  152. }
  153. tree = SegmentTree(n);
  154. tree.build(1, 0, n - 1, arr);
  155. for (int w = 0; w < q; ++w) {
  156. int type, l, r;
  157. cin >> type >> l >> r;
  158. if (type == 0 || type == 1) {
  159. tree.set(1, 0, n - 1, l, r, type);
  160. } else if (type == 2) {
  161. tree.reverse(1, 0, n - 1, l, r);
  162. } else if (type == 3) {
  163. Info res = tree.query(1 ,0, n - 1, l, r);
  164. cout << res.cnt[1] << '\n';
  165. } else if (type == 4) {
  166. Info res = tree.query(1 ,0, n - 1, l, r);
  167. cout << res.l[1] << '\n';
  168. } else {
  169. assert(false);
  170. }
  171. }
  172. return 0;
  173. }
  174.  
Success #stdin #stdout 0s 5264KB
stdin
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
stdout
5
2
6
5