Submission #654428

#TimeUsernameProblemLanguageResultExecution timeMemory
654428Valera_GrinenkoSjeckanje (COCI21_sjeckanje)C++17
55 / 110
2097 ms90844 KiB
#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 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...