#include<bits/stdc++.h>
using namespace std;
// actual values
struct SegTree {
vector<long long int> add1, add2; // constant, difference
vector<long long int> val; // set
vector<bool> lazy; // true if set
SegTree(int n, vector<long long int> &a) {
add1.assign(4 * n, 0);
add2.assign(4 * n, 0);
val.resize(4 * n);
lazy.assign(4 * n, false);
build(1, 0, n - 1, a);
}
void build(int v, int tl, int tr, vector<long long int> &a) {
if (tl == tr) {
val[v] = a[tl];
lazy[v] = true;
return;
}
int mid = tl + (tr - tl) / 2;
build(2 * v, tl, mid, a);
build(2 * v + 1, mid + 1, tr, a);
}
int push(int v, int tl, int tr) {
int mid = tl + (tr - tl) / 2;
if (lazy[v]) {
val[2 * v] = val[v];
val[2 * v + 1] = val[v];
lazy[v] = false;
lazy[2 * v] = true;
lazy[2 * v + 1] = true;
}
add1[2 * v] += add1[v];
add1[2 * v + 1] += add1[v] + (mid + 1 - tl) * add2[v];
add2[2 * v] += add2[v];
add2[2 * v + 1] += add2[v];
add1[v] = add2[v] = 0;
return mid;
}
// affine add
void update1(int v, int tl, int tr, int l, int r, long long int start, long long int diff) {
if (l > r) return;
if (tl == l && tr == r) {
add1[v] += start;
add2[v] += diff;
return;
}
int mid = push(v, tl, tr);
update1(2 * v, tl, mid, l, min(mid, r), start, diff);
update1(2 * v + 1, mid + 1, tr, max(mid + 1, l), r, start + (mid + 1 - tl) * diff, diff);
}
// range set
void update2(int v, int tl, int tr, int l, int r, long long int x) {
if (l > r) return;
if (tl == l && tr == r) {
add1[v] = 0;
add2[v] = 0;
lazy[v] = true;
val[v] = x;
return;
}
int mid = push(v, tl, tr);
update2(2 * v, tl, mid, l, min(mid, r), x);
update2(2 * v + 1, mid + 1, tr, max(mid + 1, l), r, x);
}
long long int query(int v, int tl, int tr, int idx) {
if (tl == tr) return val[v] + add1[v];
int mid = push(v, tl, tr);
if (idx <= mid) return query(2 * v, tl, mid, idx);
else return query(2 * v + 1, mid + 1, tr, idx);
}
};
struct Data {
int ans, sz;
long long int lDiff, rDiff;
int lCnt, rCnt;
};
Data merge(Data l, Data r) {
if (l.sz == 0) return r;
if (r.sz == 0) return l;
Data res;
res.sz = l.sz + r.sz;
res.ans = max(l.ans, r.ans);
res.lDiff = l.lDiff;
res.lCnt = l.lCnt + (l.lCnt == l.sz && r.lDiff == l.lDiff ? r.lCnt : 0);
res.rDiff = r.rDiff;
res.rCnt = r.rCnt + (r.rCnt == r.sz && l.rDiff == r.rDiff ? l.rCnt : 0);
if (l.rDiff == r.lDiff) res.ans = max(res.ans, l.rCnt + r.lCnt);
return res;
}
struct SegTree2 {
vector<Data> st;
vector<long long int> add; // add
vector<long long int> val; // set
vector<bool> lazy;
SegTree2(int n, vector<long long int> &a) {
st.resize(4 * n);
add.assign(4 * n, 0);
val.resize(4 * n);
lazy.assign(4 * n, false);
build(1, 0, n - 1, a);
}
void build(int v, int tl, int tr, vector<long long int> &a) {
if (tl == tr) {
st[v].sz = st[v].ans = st[v].lCnt = st[v].rCnt = 1;
st[v].lDiff = st[v].rDiff = a[tl + 1] - a[tl];
return;
}
int mid = tl + (tr - tl) / 2;
build(2 * v, tl, mid, a);
build(2 * v + 1, mid + 1, tr, a);
st[v] = merge(st[2 * v], st[2 * v + 1]);
}
void push(int v) {
if (lazy[v]) {
st[2 * v].ans = st[2 * v].lCnt = st[2 * v].rCnt = st[2 * v].sz;
st[2 * v].lDiff = st[2 * v].rDiff = val[v];
st[2 * v + 1].ans = st[2 * v + 1].lCnt = st[2 * v + 1].rCnt = st[2 * v + 1].sz;
st[2 * v + 1].lDiff = st[2 * v + 1].rDiff = val[v];
val[2 * v] = val[2 * v + 1] = val[v];
lazy[v] = false;
lazy[2 * v] = lazy[2 * v + 1] = true;
}
st[2 * v].lDiff += add[v];
st[2 * v].rDiff += add[v];
st[2 * v + 1].lDiff += add[v];
st[2 * v + 1].rDiff += add[v];
add[2 * v] += add[v];
add[2 * v + 1] += add[v];
add[v] = 0;
}
// range add
void update1(int v, int tl, int tr, int l, int r, long long int x) {
if (l > r) return;
if (tl == l && tr == r) {
add[v] += x;
st[v].lDiff += x;
st[v].rDiff += x;
return;
}
push(v);
int mid = tl + (tr - tl) / 2;
update1(2 * v, tl, mid, l, min(mid, r), x);
update1(2 * v + 1, mid + 1, tr, max(mid + 1, l), r, x);
st[v] = merge(st[2 * v], st[2 * v + 1]);
}
// range set
void update2(int v, int tl, int tr, int l, int r, long long int x) {
if (l > r) return;
if (tl == l && tr == r) {
add[v] = 0;
lazy[v] = true;
val[v] = x;
st[v].ans = st[v].lCnt = st[v].rCnt = st[v].sz;
st[v].lDiff = st[v].rDiff = x;
return;
}
push(v);
int mid = tl + (tr - tl) / 2;
update2(2 * v, tl, mid, l, min(mid, r), x);
update2(2 * v + 1, mid + 1, tr, max(mid + 1, l), r, x);
st[v] = merge(st[2 * v], st[2 * v + 1]);
}
Data query(int v, int tl, int tr, int l, int r) {
if (l > r) {
Data res;
res.sz = res.ans = 0;
return res;
}
if (tl == l && tr == r) return st[v];
push(v);
int mid = tl + (tr - tl) / 2;
return merge(
query(2 * v, tl, mid, l, min(mid, r)),
query(2 * v + 1, mid + 1, tr, max(mid + 1, l), r)
);
}
};
void solve() {
int n,q; cin >> n >> q;
vector<long long int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
SegTree st1(n, a);
SegTree2 st2(n - 1, a);
while (q--) {
int t; cin >> t;
int l,r; cin >> l >> r;
l--; r--;
if (t == 1) {
long long int s,c; cin >> s >> c;
st1.update1(1, 0, n - 1, l, r, s, c);
if (l) {
long long int val1 = st1.query(1, 0, n - 1, l - 1);
long long int val2 = st1.query(1, 0, n - 1, l);
st2.update2(1, 0, n - 2, l - 1, l - 1, val2 - val1);
}
if (r + 1 < n) {
long long int val1 = st1.query(1, 0, n - 1, r);
long long int val2 = st1.query(1, 0, n - 1, r + 1);
st2.update2(1, 0, n - 2, r, r, val2 - val1);
}
st2.update1(1, 0, n - 2, l, r - 1, c);
} else if (t == 2) {
long long int s,c; cin >> s >> c;
st1.update2(1, 0, n - 1, l, r, s);
st1.update1(1, 0, n - 1, l, r, 0, c);
if (l) {
long long int val1 = st1.query(1, 0, n - 1, l - 1);
long long int val2 = st1.query(1, 0, n - 1, l);
st2.update2(1, 0, n - 2, l - 1, l - 1, val2 - val1);
}
if (r + 1 < n) {
long long int val1 = st1.query(1, 0, n - 1, r);
long long int val2 = st1.query(1, 0, n - 1, r + 1);
st2.update2(1, 0, n - 2, r, r, val2 - val1);
}
st2.update2(1, 0, n - 2, l, r - 1, c);
} else {
Data res = st2.query(1, 0, n - 2, l, r - 1);
cout << res.ans + 1 << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t = 1;
while (t--) {
solve();
}
}
# | 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... |