답안 #654428

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
654428 2022-10-31T09:42:40 Z Valera_Grinenko Sjeckanje (COCI21_sjeckanje) C++17
55 / 110
2000 ms 90844 KB
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
typedef long long ll;
typedef long double ld;
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> bool umin (T &a, T b) {return a > b ? (a = b, true) : false; }
template<class T> bool umax (T &a, T b) {return a < b ? (a = b, true) : false; }
struct node {
  //mask (2^0 * mn_taken + 2^1 * mx_taken)
  ll one[4] = {0}; //node is one block
  ll two[4][4] = {0}; //node is two blocks
};
node id;
node comb(node a, node b) {
  node c = id;
  for(int one_a = 0; one_a < 4; one_a++)
    for(int one_b = 0; one_b < 4; one_b++) {
      if(!(one_a & one_b) || (one_a == 3 && one_b == 3))
        umax(c.one[(one_a | one_b)], a.one[one_a] + b.one[one_b]);
      umax(c.two[one_a][one_b], a.one[one_a] + b.one[one_b]);
    }
  for(int i = 0; i < 4; i++)
    for(int j = 0; j < 4; j++) {
      umax(c.two[i][j], a.two[i][3] + b.two[3][j]);
      for(int k = 0; k < 4; k++) {
        //one_a, l_b, r_b
        if((i & j) == 0 || (i == 3 && j == 3)) {
          umax(c.two[(i | j)][k], a.one[i] + b.two[j][k]);
        }
        //l_a, r_a, one_b
        if((j & k) == 0 || (j == 3 && k == 3)) {
          umax(c.two[i][(j | k)], a.two[i][j] + b.one[k]);
        }
        //l_a, r_a, r_b. l_b = (3 ^ r_a)
        umax(c.two[i][k], a.two[i][j] + b.two[(3 ^ j)][k]);
      }
    }
  return c;
}
const int N = 2e5 + 42;
node st[4 * N];
ll lazy[4 * N];
void push(int v) {
  if(lazy[v]) {
    st[(v << 1)].one[1] -= lazy[v];
    st[(v << 1)].one[2] += lazy[v];
    st[(v << 1) + 1].one[1] -= lazy[v];
    st[(v << 1) + 1].one[2] += lazy[v];
    st[(v << 1)].two[0][1] += -1 * lazy[v];
    st[(v << 1) + 1].two[0][1] += -1 * lazy[v];
    st[(v << 1)].two[0][2] += 1 * lazy[v];
    st[(v << 1) + 1].two[0][2] += 1 * lazy[v];
    st[(v << 1)].two[1][0] += -1 * lazy[v];
    st[(v << 1) + 1].two[1][0] += -1 * lazy[v];
    st[(v << 1)].two[1][1] += -2 * lazy[v];
    st[(v << 1) + 1].two[1][1] += -2 * lazy[v];
    st[(v << 1)].two[1][3] += -1 * lazy[v];
    st[(v << 1) + 1].two[1][3] += -1 * lazy[v];
    st[(v << 1)].two[2][0] += 1 * lazy[v];
    st[(v << 1) + 1].two[2][0] += 1 * lazy[v];
    st[(v << 1)].two[2][2] += 2 * lazy[v];
    st[(v << 1) + 1].two[2][2] += 2 * lazy[v];
    st[(v << 1)].two[2][3] += 1 * lazy[v];
    st[(v << 1) + 1].two[2][3] += 1 * lazy[v];
    st[(v << 1)].two[3][1] += -1 * lazy[v];
    st[(v << 1) + 1].two[3][1] += -1 * lazy[v];
    st[(v << 1)].two[3][2] += 1 * lazy[v];
    st[(v << 1) + 1].two[3][2] += 1 * lazy[v];
    lazy[(v << 1)] += lazy[v];
    lazy[(v << 1) + 1] += lazy[v];
    lazy[v] = 0;
  }
}
ll a[N];
void build(int v, int tl, int tr) {
  if(tl == tr) {
    st[v] = id;
    st[v].one[0] = 0;
    st[v].one[1] = -a[tl];
    st[v].one[2] = a[tl];
    st[v].one[3] = 0;
    st[v].two[3][0] = 0;
    st[v].two[2][0] = a[tl];
    st[v].two[1][0] = -a[tl];
    st[v].two[0][3] = 0;
    st[v].two[0][2] = a[tl];
    st[v].two[0][1] = -a[tl];
    return;
  }
  int tm = (tl + tr) / 2;
  build((v << 1), tl, tm);
  build((v << 1) + 1, tm + 1, tr);
  st[v] = comb(st[(v << 1)], st[(v << 1) + 1]);
  // cout << tl << ' ' << tr << '\n';
  // for(int i = 0; i < 4; i++) cout << st[v].one[i] << ' ';
  // cout << '\n';
  // for(int i = 0; i < 4; i++) {
  //   for(int j = 0; j < 4; j++) {
  //     cout << st[v].two[i][j] << ' ';
  //   }
  //   cout << '\n';
  // }
  // cout << '\n';
}
void upd(int v, int tl, int tr, int l, int r, int x) {
  if(l > r) return;
  if(l == tl && r == tr) {
    st[v].one[1] -= x;
    st[v].one[2] += x;
    for(int l = 0; l < 4; l++)
      for(int r = 0; r < 4; r++) {
        int add = 0;
        if(l == 1) add--;
        else if(l == 2) add++;
        if(r == 1) add--;
        else if(r == 2) add++;
        st[v].two[l][r] += add * x;
      }
    lazy[v] += x;
    return;
  }
  push(v);
  int tm = (tl + tr) / 2;
  upd((v << 1), tl, tm, l, min(r, tm), x);
  upd((v << 1) + 1, tm + 1, tr, max(l, tm + 1), r, x);
  st[v] = comb(st[(v << 1)], st[(v << 1) + 1]);
  // cout << tl << ' ' << tr << '\n';
  // for(int i = 0; i < 4; i++) cout << st[v].one[i] << ' ';
  // cout << '\n';
  // for(int i = 0; i < 4; i++) {
  //   for(int j = 0; j < 4; j++) {
  //     cout << st[v].two[i][j] << ' ';
  //   }
  //   cout << '\n';
  // }
  // cout << '\n';
}
ll stupid(int n) {
  vector<ll> ans(n + 1);
  for(int i = 0; i < n; i++) {
    ll mn = 1e9, mx = -1e9;
    for(int j = i + 1; j <= n; j++) {
      mn = min(mn, a[j - 1]);
      mx = max(mx, a[j - 1]);
      ans[j] = max(ans[j], ans[i] + mx - mn);
    }
  }
  return ans[n];
}
void solve() {
  for(int i = 0; i < 4; i++) {
    id.one[i] = -1e18;
    for(int j = 0; j < 4; j++) {
      id.two[i][j] = -1e18;
    }
    id.one[0] = 0;
  }
  int n, q;
  cin >> n >> q;
  for(int i = 0; i < n; i++) cin >> a[i];
  build(1, 0, n - 1);
  while(q--) {
    int l, r, x;
    // l = rng() % n, r = rng() % n;
    // x = rng() % (2 * n) - rng() % n;
    // if(l > r) swap(l, r);
    cin >> l >> r >> x; l--; r--;
    // for(int i = l; i <= r; i++) a[i] += x;
    // for(int i = 0; i < n; i++) cout << a[i] << ' ';
    // cout << '\n';
    upd(1, 0, n - 1, l, r, x);
    ll ans = 0;
    umax(ans, max(st[1].one[3], st[1].one[0]));
    umax(ans, max(st[1].two[0][0], st[1].two[0][3]));
    umax(ans, max(st[1].two[3][0], st[1].two[3][3]));
    cout << ans << '\n';
    // cout << stupid(n) << '\n';
    // if(ans != stupid(n)) exit(0);
  }
}
int main() {

  ios::sync_with_stdio(0); cin.tie(0);

  int t = 1;

  // cin >> t;

  while(t--) solve();

  return 0;
}
/*
12 1
25 65 111 108 105 106 75 88 62 34 7 0
1 1 0

20 1
35 62 108 106 122 101 105 79 98 115 156 147 120 90 120 116 116 35 26 -12
1 1 0
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 340 KB Output is correct
2 Correct 2 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 436 KB Output is correct
5 Correct 2 ms 340 KB Output is correct
6 Correct 2 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 340 KB Output is correct
2 Correct 2 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 436 KB Output is correct
5 Correct 2 ms 340 KB Output is correct
6 Correct 2 ms 340 KB Output is correct
7 Correct 27 ms 1764 KB Output is correct
8 Correct 26 ms 1744 KB Output is correct
9 Correct 26 ms 1748 KB Output is correct
10 Correct 26 ms 1748 KB Output is correct
11 Correct 29 ms 1740 KB Output is correct
12 Correct 27 ms 1760 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 340 KB Output is correct
2 Correct 2 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 436 KB Output is correct
5 Correct 2 ms 340 KB Output is correct
6 Correct 2 ms 340 KB Output is correct
7 Correct 27 ms 1764 KB Output is correct
8 Correct 26 ms 1744 KB Output is correct
9 Correct 26 ms 1748 KB Output is correct
10 Correct 26 ms 1748 KB Output is correct
11 Correct 29 ms 1740 KB Output is correct
12 Correct 27 ms 1760 KB Output is correct
13 Execution timed out 2097 ms 90844 KB Time limit exceeded
14 Halted 0 ms 0 KB -