fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using ll = long long;
  5. static const ll NEG = -(1LL << 60);
  6.  
  7. struct node {
  8. ll dp[2][2];
  9. };
  10.  
  11. int n, q;
  12. vector<ll> a;
  13. vector<node> st;
  14. int sz;
  15.  
  16. node make_leaf(ll x) {
  17. node t;
  18. for (int i = 0; i < 2; ++i)
  19. for (int j = 0; j < 2; ++j)
  20. t.dp[i][j] = NEG;
  21.  
  22. // dp[l][r]:
  23. // l = trạng thái chọn ở đầu đoạn
  24. // r = trạng thái chọn ở cuối đoạn
  25. // với đoạn 1 phần tử, 4 trạng thái cơ bản
  26. t.dp[0][0] = 0; // không chọn gì
  27. t.dp[1][1] = x; // chọn phần tử này
  28. return t;
  29. }
  30.  
  31. node merge_node(const node &L, const node &R) {
  32. node res;
  33. for (int i = 0; i < 2; ++i)
  34. for (int j = 0; j < 2; ++j)
  35. res.dp[i][j] = NEG;
  36.  
  37. for (int l1 = 0; l1 < 2; ++l1) {
  38. for (int r1 = 0; r1 < 2; ++r1) {
  39. if (L.dp[l1][r1] == NEG) continue;
  40. for (int l2 = 0; l2 < 2; ++l2) {
  41. for (int r2 = 0; r2 < 2; ++r2) {
  42. if (R.dp[l2][r2] == NEG) continue;
  43.  
  44. // không được chọn cả cuối trái và đầu phải
  45. if (r1 == 1 && l2 == 1) continue;
  46.  
  47. int nl = l1;
  48. int nr = r2;
  49. res.dp[nl][nr] = max(res.dp[nl][nr], L.dp[l1][r1] + R.dp[l2][r2]);
  50. }
  51. }
  52. }
  53. }
  54. return res;
  55. }
  56.  
  57. void build() {
  58. for (int i = sz - 1; i >= 1; --i) {
  59. st[i] = merge_node(st[i << 1], st[i << 1 | 1]);
  60. }
  61. }
  62.  
  63. void update(int pos, ll val) {
  64. int p = sz + pos - 1;
  65. st[p] = make_leaf(val);
  66. for (p >>= 1; p; p >>= 1) {
  67. st[p] = merge_node(st[p << 1], st[p << 1 | 1]);
  68. }
  69. }
  70.  
  71. node query(int l, int r) {
  72. node left, right;
  73. bool hasLeft = false, hasRight = false;
  74.  
  75. for (int i = 0; i < 2; ++i)
  76. for (int j = 0; j < 2; ++j)
  77. left.dp[i][j] = right.dp[i][j] = NEG;
  78.  
  79. l = l + sz - 1;
  80. r = r + sz - 1;
  81.  
  82. while (l <= r) {
  83. if (l & 1) {
  84. if (!hasLeft) {
  85. left = st[l];
  86. hasLeft = true;
  87. } else {
  88. left = merge_node(left, st[l]);
  89. }
  90. ++l;
  91. }
  92. if (!(r & 1)) {
  93. if (!hasRight) {
  94. right = st[r];
  95. hasRight = true;
  96. } else {
  97. right = merge_node(st[r], right);
  98. }
  99. --r;
  100. }
  101. l >>= 1;
  102. r >>= 1;
  103. }
  104.  
  105. if (!hasLeft) return right;
  106. if (!hasRight) return left;
  107. return merge_node(left, right);
  108. }
  109.  
  110. int main() {
  111. ios::sync_with_stdio(false);
  112. cin.tie(nullptr);
  113.  
  114. cin >> n >> q;
  115. a.assign(n + 1, 0);
  116. for (int i = 1; i <= n; ++i) cin >> a[i];
  117.  
  118. sz = 1;
  119. while (sz < n) sz <<= 1;
  120. st.assign(sz << 1, make_leaf(NEG));
  121.  
  122. for (int i = 1; i <= n; ++i) st[sz + i - 1] = make_leaf(a[i]);
  123. for (int i = n + 1; i <= sz; ++i) st[sz + i - 1] = make_leaf(NEG);
  124.  
  125. build();
  126.  
  127. while (q--) {
  128. int type;
  129. cin >> type;
  130. if (type == 1) {
  131. int x;
  132. ll y;
  133. cin >> x >> y;
  134. a[x] = y;
  135. update(x, y);
  136. } else {
  137. int l, r;
  138. cin >> l >> r;
  139. node ans = query(l, r);
  140. ll best = NEG;
  141. for (int i = 0; i < 2; ++i)
  142. for (int j = 0; j < 2; ++j)
  143. best = max(best, ans.dp[i][j]);
  144. cout << best << '\n';
  145. }
  146. }
  147.  
  148. return 0;
  149. }
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
Standard output is empty