제출 #602356

#제출 시각아이디문제언어결과실행 시간메모리
602356verngutzProgression (NOI20_progression)C++17
48 / 100
3069 ms61536 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; } struct segtree { segtree* l; segtree* r; int L, R; bool is_lazy; ll front, back, delta; int longest_suff, longest_pref, longest, longest_start_index; segtree(vector<ll>& a, int L, int R): L(L), R(R), is_lazy(false), delta(0) { if(R - L > 1) { int M = (L + R) / 2; l = new segtree(a, L, M); r = new segtree(a, M, R); combine(); } else { l = nullptr; r = nullptr; front = back = a[L]; longest_suff = 1; longest_pref = 1; longest = 1; longest_start_index = L; } } int len() { return R - L; } void combine() { front = l->get_front(); back = r->get_back(); bool can_cross = l->get_back() == r->get_front(); longest_suff = r->longest_suff; if(r->longest_suff == r->len() && can_cross) { longest_suff += l->longest_suff; } longest_pref = l->longest_pref; if(l->longest_pref == l->len() && can_cross) { longest_pref += r->longest_pref; } int crossing = can_cross ? l->longest_suff + r->longest_pref : 0; longest = max({l->longest, r->longest, crossing}); if(longest == r->longest) { longest_start_index = r->longest_start_index; } else if(longest == crossing) { int M = (L + R) / 2; longest_start_index = M - l->longest_suff; } else { longest_start_index = l->longest_start_index; } } void lazy(ll x) { is_lazy = true; delta += x; } void unlazy() { if(is_lazy) { if(len() > 1) { l->lazy(delta); r->lazy(delta); } is_lazy = false; delta = 0; combine(); } } ll get_front() { return is_lazy ? front + delta : front; } ll get_back() { return is_lazy ? back + delta : back; } 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 { unlazy(); 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); bool can_cross = l->get_back() == r->get_front() ; int crossing = can_cross ? min(l->longest_suff, M - s) + min(r->longest_pref, e - M) : 0; int crossing_start_index = can_cross ? max(M - l->longest_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}; } } void increment(int s, int e, ll x) { if(s <= L and R <= e) { lazy(x); } else if(R <= s or e <= L) { return; } else { unlazy(); l->increment(s, e, x); r->increment(s, e, x); combine(); } } ~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), a(n); cin >> d; adjacent_difference(d.begin(), d.end(), a.begin()); segtree st(a, 0, n); while(q--) { int t; cin >> t; if(t == 1) { int L, R, S, C; cin >> L >> R >> S >> C; L--, R--; st.increment(L, L + 1, S); if(R + 1 < n) { st.increment(R + 1, R + 2, -S); } st.increment(L + 1, R + 1, C); if(R + 1 < n) { st.increment(R + 1, R + 2, ll(R - L) * -C); } } 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 + ll(i - L) * C; } adjacent_difference(d.begin(), d.end(), a.begin()); } 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...