답안 #654427

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
654427 2022-10-31T09:39:30 Z Valera_Grinenko Sjeckanje (COCI21_sjeckanje) C++17
55 / 110
2000 ms 94208 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]);
      }
    }
  umax(c.two[0][3], c.two[3][3]);
  umax(c.two[3][0], c.two[3][3]);
  umax(c.two[0][0], c.two[3][3]);
  umax(c.two[0][0], c.two[0][3]);
  umax(c.two[0][0], c.two[3][0]);
  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];
    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 << 1)].two[l][r] += add * lazy[v];
        st[(v << 1) + 1].two[l][r] += add * 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 3 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 340 KB Output is correct
5 Correct 3 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 3 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 340 KB Output is correct
5 Correct 3 ms 340 KB Output is correct
6 Correct 2 ms 340 KB Output is correct
7 Correct 30 ms 1836 KB Output is correct
8 Correct 38 ms 1816 KB Output is correct
9 Correct 37 ms 1812 KB Output is correct
10 Correct 39 ms 1944 KB Output is correct
11 Correct 41 ms 1824 KB Output is correct
12 Correct 39 ms 1836 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 340 KB Output is correct
2 Correct 3 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 340 KB Output is correct
5 Correct 3 ms 340 KB Output is correct
6 Correct 2 ms 340 KB Output is correct
7 Correct 30 ms 1836 KB Output is correct
8 Correct 38 ms 1816 KB Output is correct
9 Correct 37 ms 1812 KB Output is correct
10 Correct 39 ms 1944 KB Output is correct
11 Correct 41 ms 1824 KB Output is correct
12 Correct 39 ms 1836 KB Output is correct
13 Execution timed out 2082 ms 94208 KB Time limit exceeded
14 Halted 0 ms 0 KB -