紫应该也算红的一种(
萌新第亿天学 OI,由于自己不够努力,不会写区间最值线段树板子。
WA 0 pts。
请大神求调,码风凉嚎,代码小氢锌。
附代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 10;
const int INF = 1e9;
int n, m, a[N];
struct Segment_Tree{
#define lson rt<<1,l,md
#define rson rt<<1|1,md+1,r
static const int MR = 5e5 + 10;
struct Node{
int sum, mx, mx2, mn, mn2, cmx, cmn;
int tmx, tmn, add;
}xds[MR << 2];
void Push_Up(int rt){
xds[rt].sum = xds[rt << 1].sum + xds[rt << 1 | 1].sum;
if (xds[rt << 1].mx == xds[rt << 1 | 1].mx){
xds[rt].mx = xds[rt << 1].mx;
xds[rt].mx2 = max(xds[rt << 1].mx2, xds[rt << 1 | 1].mx2);
xds[rt].cmx = xds[rt << 1].cmx + xds[rt << 1 | 1].cmx;
}else if (xds[rt << 1].mx > xds[rt << 1 | 1].mx){
xds[rt].mx = xds[rt << 1].mx;
xds[rt].mx2 = max(xds[rt << 1].mx2, xds[rt << 1 | 1].mx);
xds[rt].cmx = xds[rt << 1].cmx;
}else{
xds[rt].mx = xds[rt << 1 | 1].mx;
xds[rt].mx2 = max(xds[rt << 1].mx, xds[rt << 1 | 1].mx2);
xds[rt].cmx = xds[rt << 1 | 1].cmx;
}
if (xds[rt << 1].mn == xds[rt << 1 | 1].mn){
xds[rt].mn = xds[rt << 1].mn;
xds[rt].mn2 = min(xds[rt << 1].mn2, xds[rt << 1 | 1].mn2);
xds[rt].cmn = xds[rt << 1].cmn + xds[rt << 1 | 1].cmn;
}else if (xds[rt << 1].mn < xds[rt << 1 | 1].mn){
xds[rt].mn = xds[rt << 1].mn;
xds[rt].mn2 = min(xds[rt << 1].mn2, xds[rt << 1 | 1].mn);
xds[rt].cmn = xds[rt << 1].cmn;
}else{
xds[rt].mn = xds[rt << 1 | 1].mn;
xds[rt].mn2 = min(xds[rt << 1].mn, xds[rt << 1 | 1].mn2);
xds[rt].cmn = xds[rt << 1 | 1].cmn;
}
}
void Push_Add(int rt, int l, int r, int k){
xds[rt].sum = (r - l + 1) * k;
xds[rt].add += k;
xds[rt].mx += k;
if (xds[rt].mx2 != -INF)
xds[rt].mx2 += k;
if (xds[rt].tmx != -INF)
xds[rt].tmx += k;
xds[rt].mn += k;
if (xds[rt].mn2 != INF)
xds[rt].mn2 += k;
if (xds[rt].tmn != INF)
xds[rt].tmn += k;
}
void Push_Min(int rt, int k){
if (xds[rt].mx <= k)
return;
xds[rt].sum -= xds[rt].cmx * (xds[rt].mx - k);
xds[rt].mx = k;
xds[rt].tmn = k;
if (xds[rt].mn == xds[rt].mx)
xds[rt].mn = k;
if (xds[rt].mn2 == xds[rt].mx)
xds[rt].mn2 = k;
if (xds[rt].tmx > k)
xds[rt].tmx = k;
}
void Push_Max(int rt, int k){
if (xds[rt].mn >= k)
return;
xds[rt].sum += xds[rt].cmn * (k - xds[rt].mn);
xds[rt].mn = k;
xds[rt].tmx = k;
if (xds[rt].mx == xds[rt].mn)
xds[rt].mx = k;
if (xds[rt].mx2 == xds[rt].mn)
xds[rt].mx2 = k;
if (xds[rt].tmn < k)
xds[rt].tmn = k;
}
void Push_Down(int rt, int l, int r){
int md = (l + r) >> 1;
if (xds[rt].add){
Push_Add(rt << 1, l, md, xds[rt].add);
Push_Add(rt << 1 | 1, md + 1, r, xds[rt].add);
xds[rt].add = 0;
}
if (xds[rt].tmx != -INF){
Push_Max(rt << 1, xds[rt].tmx);
Push_Max(rt << 1 | 1, xds[rt].tmx);
xds[rt].tmx = -INF;
}
if (xds[rt].tmn != INF){
Push_Min(rt << 1, xds[rt].tmn);
Push_Min(rt << 1 | 1, xds[rt].tmn);
xds[rt].tmn = INF;
}
}
void Build(int rt, int l, int r){
xds[rt].add = 0;
xds[rt].tmx = -INF;
xds[rt].tmn = INF;
if (l == r){
xds[rt].mx = a[l];
xds[rt].mn = a[l];
xds[rt].mx2 = -INF;
xds[rt].mn2 = INF;
xds[rt].sum = a[l];
xds[rt].cmx = 1;
xds[rt].cmn = 1;
return;
}
int md = (l + r) >> 1;
Build(lson);
Build(rson);
Push_Up(rt);
}
void Update_Add(int rt, int l, int r, int x, int y, int k){
if (x <= l && r <= y){
Push_Add(rt, l, r, k);
return;
}
Push_Down(rt, l, r);
int md = (l + r) >> 1;
if (x <= md)
Update_Add(lson, x, y, k);
if (y > md)
Update_Add(rson, x, y, k);
Push_Up(rt);
}
void Update_Max(int rt, int l, int r, int x, int y, int k){
if (xds[rt].mn >= k)
return;
if (x <= l && r <= y && xds[rt].mn2 > k){
Push_Max(rt, k);
return;
}
Push_Down(rt, l, r);
int md = (l + r) >> 1;
if (x <= md)
Update_Max(lson, x, y, k);
if (y > md)
Update_Max(rson, x, y, k);
Push_Up(rt);
}
void Update_Min(int rt, int l, int r, int x, int y, int k){
if (xds[rt].mx <= k)
return;
if (x <= l && r <= y && xds[rt].mx2 < k){
Push_Min(rt, k);
return;
}
Push_Down(rt, l, r);
int md = (l + r) >> 1;
if (x <= md)
Update_Min(lson, x, y, k);
if (y > md)
Update_Min(rson, x, y, k);
Push_Up(rt);
}
int Query_Sum(int rt, int l, int r, int x, int y){
if (x <= l && r <= y)
return xds[rt].sum;
Push_Down(rt, l, r);
int md = (l + r) >> 1;
int res = 0;
if (x <= md)
res += Query_Sum(lson, x, y);
if (y > md)
res += Query_Sum(rson, x, y);
return res;
}
int Query_Max(int rt, int l, int r, int x, int y){
if (x <= l && r <= y)
return xds[rt].mx;
Push_Down(rt, l, r);
int md = (l + r) >> 1;
int res = -INF;
if (x <= md)
res = max(res, Query_Max(lson, x, y));
if (y > md)
res = max(res, Query_Max(rson, x, y));
return res;
}
int Query_Min(int rt, int l, int r, int x, int y){
if (x <= l && r <= y)
return xds[rt].mn;
Push_Down(rt, l, r);
int md = (l + r) >> 1;
int res = INF;
if (x <= md)
res = min(res, Query_Min(lson, x, y));
if (y > md)
res = min(res, Query_Min(rson, x, y));
return res;
}
}sgt;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sgt.Build(1, 1, n);
cin >> m;
for (int i = 1, op, l, r, x; i <= m; i++){
cin >> op;
if (op == 1){
cin >> l >> r >> x;
sgt.Update_Add(1, 1, n, l, r, x);
}else if (op == 2){
cin >> l >> r >> x;
sgt.Update_Max(1, 1, n, l, r, x);
}else if (op == 3){
cin >> l >> r >> x;
sgt.Update_Min(1, 1, n, l, r, x);
}else if (op == 4){
cin >> l >> r;
cout << sgt.Query_Sum(1, 1, n, l, r) << endl;
}else if (op == 5){
cin >> l >> r;
cout << sgt.Query_Max(1, 1, n, l, r) << endl;
}else if (op == 6){
cin >> l >> r;
cout << sgt.Query_Min(1, 1, n, l, r) << endl;
}
}
return 0;
}