萌新求调红题!玄关!
查看原帖
萌新求调红题!玄关!
638491
Illus1onary_Real1ty楼主2024/8/8 20:36

紫应该也算红的一种(

萌新第亿天学 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;
}
2024/8/8 20:36
加载中...