Submission #601998

#TimeUsernameProblemLanguageResultExecution timeMemory
601998verngutzProgression (NOI20_progression)C++17
50 / 100
3070 ms41036 KiB
#include <bits/stdc++.h> #define err(args...) {} #ifdef DEBUG #include "_debug.cpp" #endif using namespace std; using ll = long long; using ld = long double; template <typename T> using lim = numeric_limits<T>; template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; } template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; } vector<ll> a; struct segtree { segtree* l; segtree* r; int L, R; int longest_eq_suff, longest_eq_pref, longest, longest_start_index; segtree(int L, int R): L(L), R(R) { if(R - L > 1) { int M = (L + R) / 2; l = new segtree(L, M); r = new segtree(M, R); } else { l = nullptr; r = nullptr; } } void build() { if(R - L > 1) { int M = (L + R) / 2; r->build(); l->build(); longest_eq_suff = r->longest_eq_suff; if(r->longest_eq_suff == r->len() && l->back() == r->front()) { longest_eq_suff += l->longest_eq_suff; } longest_eq_pref = l->longest_eq_pref; if(l->longest_eq_pref == l->len() && l->back() == r->front()) { longest_eq_pref += r->longest_eq_pref; } int crossing = l->back() == r->front() ? l->longest_eq_suff + r->longest_eq_pref : 0; longest = max({l->longest, r->longest, crossing}); if(longest == r->longest) { longest_start_index = r->longest_start_index; } else if(longest == crossing) { longest_start_index = M - l->longest_eq_suff; } else { longest_start_index = l->longest_start_index; } } else { longest_eq_suff = 1; longest_eq_pref = 1; longest = 1; longest_start_index = L; } } int front() { return a[L]; } int back() { return a[R - 1]; } int len() { return R - L; } pair<int, int> query(int s, int e) { if(s <= L and R <= e) { return {longest, longest_start_index}; } else if(R <= s or e <= L) { return {0, -1}; } else { int M = (L + R) / 2; auto [L_longest, L_start_index] = l->query(s, e); auto [R_longest, R_start_index] = r->query(s, e); int crossing = l->back() == r->front() ? min(l->longest_eq_suff, M - s) + min(r->longest_eq_pref, e - M) : 0; int crossing_start_index = l->back() == r->front() ? max(M - l->longest_eq_suff, s) : -1; int ans = max({L_longest, R_longest, crossing}); int index; if(ans == R_longest) { index = R_start_index; } else if(ans == crossing) { index = crossing_start_index; } else { index = max(L_start_index, s); } return {ans, index}; } } ~segtree() { delete l; delete r; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, q; cin >> n >> q; vector<ll> d(n); cin >> d; a.resize(n); adjacent_difference(d.begin(), d.end(), a.begin()); segtree st(0, n); st.build(); while(q--) { int t; cin >> t; if(t == 1) { int L, R, S, C; cin >> L >> R >> S >> C; L--, R--; for(int i = L; i <= R; i++) { d[i] += S + (i - L) * C; } adjacent_difference(d.begin(), d.end(), a.begin()); st.build(); } else if(t == 2) { int L, R, S, C; cin >> L >> R >> S >> C; L--, R--; for(int i = L; i <= R; i++) { d[i] = S + (i - L) * C; } adjacent_difference(d.begin(), d.end(), a.begin()); st.build(); } else { int L, R; cin >> L >> R; L--, R--; auto [longest, longest_start_index] = st.query(L, R + 1); cout << longest + (longest_start_index != L) << endl; } } return 0; }
#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...