이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |