Submission #813595

#TimeUsernameProblemLanguageResultExecution timeMemory
813595danikoynovProgression (NOI20_progression)C++14
61 / 100
3056 ms63748 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int maxn = 3e5 + 10; struct node { int left_value, right_value; int left_len, right_len; int longest, fat; node() { left_value = right_value = 0; left_len = right_len = 0; longest = 0; fat = 0; } }; node merge_nodes(node lf, node rf) { node cur; cur.left_value = lf.left_value; cur.right_value = rf.right_value; cur.left_len = lf.left_len; cur.right_len = rf.right_len; cur.longest = max(lf.longest, rf.longest); if (lf.right_value == rf.left_value) { ///cout << "merge " << " " << lf.right_len << " " << rf.left_len << endl; cur.longest = max(cur.longest, lf.right_len + rf.left_len); if (lf.fat) cur.left_len += rf.left_len; if (rf.fat) cur.right_len += lf.right_len; if (lf.fat && rf.fat) { cur.fat = true; cur.left_len = cur.longest; cur.right_len = cur.longest; } else cur.fat = false; } return cur; } node tree[4 * maxn]; ll lazy_add[4 * maxn], lazy_set[4 * maxn], tag[4 * maxn]; void push_lazy(int root, int left, int right) { if (tag[root]) { tree[root].left_value = tree[root].right_value = lazy_set[root]; tree[root].left_len = tree[root].right_len = tree[root].longest = right - left + 1; tree[root].fat = true; if (left != right) { tag[root * 2] = tag[root * 2 + 1] = 1; lazy_set[root * 2] = lazy_set[root * 2 + 1] = lazy_set[root]; lazy_add[root * 2] = lazy_add[root * 2 + 1] = 0; } tag[root] = 0; lazy_set[root] = 0; } tree[root].left_value += lazy_add[root]; tree[root].right_value += lazy_add[root]; if (left != right) { lazy_add[root * 2] += lazy_add[root]; lazy_add[root * 2 + 1] += lazy_add[root]; } lazy_add[root] = 0; } void update_set(int root, int left, int right, int qleft, int qright, ll value) { push_lazy(root, left, right); if (left > qright || right < qleft) return; if (left >= qleft && right <= qright) { tag[root] = 1; lazy_set[root] = value; push_lazy(root, left, right); return; } int mid = (left + right) / 2; update_set(root * 2, left, mid, qleft, qright, value); update_set(root * 2 + 1, mid + 1, right, qleft, qright, value); tree[root] = merge_nodes(tree[root * 2], tree[root * 2 + 1]); ///cout << "back " << tree[root].left_value << " " << tree[root].right_value << endl; ///cout << left << " " << right << " " << tree[root * 2].right_value << " " << tree[root * 2 + 1].left_value << endl; } void update_add(int root, int left, int right, int qleft, int qright, ll value) { push_lazy(root, left, right); if (left > qright || right < qleft) return; if (left >= qleft && right <= qright) { ///cout << "update add " << left << " " << right << endl; lazy_add[root] = value; push_lazy(root, left, right); return; } int mid = (left + right) / 2; update_add(root * 2, left, mid, qleft, qright, value); update_add(root * 2 + 1, mid + 1, right, qleft, qright, value); tree[root] = merge_nodes(tree[root * 2], tree[root * 2 + 1]); } node query(int root, int left, int right, int qleft, int qright) { push_lazy(root, left, right); if (left == qleft && right == qright) return tree[root]; int mid = (left + right) / 2; if (qright <= mid) return query(root * 2, left, mid, qleft, qright); if (qleft > mid) return query(root * 2 + 1, mid + 1, right, qleft, qright); return merge_nodes(query(root * 2, left, mid, qleft, mid), query(root * 2 + 1, mid + 1, right, mid + 1, qright)); } int n, q; ll d[maxn], b[maxn]; void build_tree(int root, int left, int right) { if (left == right) { tree[root].left_value = tree[root].right_value = b[left]; tree[root].left_len = tree[root].right_len = 1; tree[root].fat = true; tree[root].longest = 1; return; } int mid = (left + right) / 2; build_tree(root * 2, left, mid); build_tree(root * 2 + 1, mid + 1, right); tree[root] = merge_nodes(tree[root * 2], tree[root * 2 + 1]); ///cout << left << " : " << right << " " << tree[root].longest << endl; } void solve() { cin >> n >> q; for (int i = 1; i <= n; i ++) cin >> d[i], b[i] = d[i] - d[i - 1]; build_tree(1, 1, n); for (int i = 1; i <= q; i ++) { int type, l, r, s, c; cin >> type >> l >> r; if (type == 1) { cin >> s >> c; for (int j = l; j <= r; j ++) { d[j] += s + (j - l) * c; b[j] += c; } update_add(1, 1, n, l, r, c); update_set(1, 1, n, l, l, d[l] - d[l - 1]); if (r != n) update_set(1, 1, n, r + 1, r + 1, d[r + 1] - d[r]); ///cout << "------------------" << endl; b[l] = d[l] - d[l - 1]; b[r + 1] = d[r + 1] - d[r]; } else if (type == 2) { cin >> s >> c; for (int j = l; j <= r; j ++) { d[j] = s + (j - l) * c; b[j] = c; } update_set(1, 1, n, l, r, c); update_set(1, 1, n, l, l, d[l] - d[l - 1]); if (r != n) update_set(1, 1, n, r + 1, r + 1, d[r + 1] - d[r]); b[l] = d[l] - d[l - 1]; b[r + 1] = d[r + 1] - d[r]; } else { if (l == r) { cout << 1 << endl; continue; } node cur = query(1, 1, n, l + 1, r); cout << cur.longest + 1 << endl; /**int len = 1, ans = 0; for (int j = l + 2; j <= r; j ++) { if (b[j] == b[j - 1]) len ++; else { ans = max(ans, len); len = 1; } } ans = max(ans, len); cout << ans + 1 << endl;*/ } /**for (int j = 1; j <= n; j ++) cout << d[j] << " "; cout << endl;*/ } } int main() { speed(); solve(); return 0; } /** 10 3 1 2 3 4 1 2 3 4 5 5 3 1 10 1 1 4 -1 -1 3 1 10 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...