萌新求调区间最值操作
查看原帖
萌新求调区间最值操作
999274
CNS_5t0_0r2楼主2024/9/23 13:44

样例已过但爆零

#include<bits/stdc++.h>
#define int long long
#define mid ((l + r) >> 1)
#define lchild (root << 1)
#define rchild ((root << 1) + 1)
using namespace std;
const int N = 5e5 + 9,INF = 1e18;

int n,m;
int a[N];

struct node{
	int sum,Max,Min;
	int se_max,se_min;
	int cnt_max,cnt_min;
	int tag_add,tag_max,tag_min;
} t[N << 2];

int len(int l,int r){
	return r - l + 1;
}

bool in_range(int l,int r,int L,int R){//[l,r]ê?·??úDT??/2é?ˉ????[L,R]?D 
	return L <= l && r <= R;
}
bool out_range(int l,int r,int L,int R){//[l,r]ê?·?ó?DT??/2é?ˉ????[L,R]?T???ˉ 
	return l > R || r < L;
}

void push_up(int root){
	t[root].sum = t[lchild].sum + t[rchild].sum;
	t[root].Max = max(t[lchild].Max,t[rchild].Max);
	t[root].Min = min(t[lchild].Min,t[rchild].Min);

	if(t[lchild].Max == t[rchild].Max){
		t[root].se_max = max(t[lchild].se_max,t[rchild].se_max);
		t[root].cnt_max = t[lchild].cnt_max + t[rchild].cnt_max;
	}
	else if(t[lchild].Max > t[rchild].Max){
		t[root].se_max = max(t[lchild].se_max,t[rchild].Max);
		t[root].cnt_max = t[lchild].cnt_max;
	}
	else{
		t[root].se_max = max(t[lchild].Max,t[rchild].se_max);
		t[root].cnt_max = t[rchild].cnt_max;
	}

	if(t[lchild].Min == t[rchild].Min){
		t[root].se_min = min(t[lchild].se_min,t[rchild].se_min);
		t[root].cnt_min = t[lchild].cnt_min + t[rchild].cnt_min;
	}
	else if(t[lchild].Min < t[rchild].Min){
		t[root].se_min = min(t[lchild].se_min,t[rchild].Min);
		t[root].cnt_min = t[lchild].cnt_min;
	}
	else{
		t[root].se_min = min(t[lchild].Min,t[rchild].se_min);
		t[root].cnt_min = t[rchild].cnt_min;
	}
}

void make_tag_add(int root,int len,int v){
	t[root].sum += len * v;
	t[root].Max += v;t[root].Min += v;
	if(t[root].se_max != -INF)
		t[root].se_max += v;
	if(t[root].se_min != INF)
		t[root].se_min += v;
	if(t[root].tag_max != -INF)
		t[root].tag_max += v;
	if(t[root].tag_min != INF)
		t[root].tag_min += v;
	t[root].tag_add += v;
}
void make_tag_max(int root,int v){
	if(t[root].Min > v)
		return;
	t[root].sum += (v - t[root].Min) * t[root].cnt_min;
	if(t[root].se_max == t[root].Min)
		t[root].se_max = v;
	if(t[root].Max == t[root].Min)
		t[root].Max = v;
	t[root].tag_min = max(t[root].tag_min,v);
	t[root].Min = v;t[root].tag_max = v;
}
void make_tag_min(int root,int v){
	if(t[root].Max <= v)
		return;
	t[root].sum += (v - t[root].Max) * t[root].cnt_max;
	if(t[root].se_min == t[root].Max)
		t[root].se_min = v;
	if(t[root].Min == t[root].Max)
		t[root].Min = v;
	t[root].tag_max = min(t[root].tag_max,v);
	t[root].Max = v;t[root].tag_min = v;
}

void push_down(int root,int l,int r){
	if(t[root].tag_add){
		make_tag_add(lchild,len(l,mid),t[root].tag_add);
		make_tag_add(rchild,len(mid + 1,r),t[root].tag_add);
	}
	if(t[root].tag_max != -INF){
		make_tag_max(lchild,t[root].tag_max);
		make_tag_max(rchild,t[root].tag_max);
	}
	if(t[root].tag_min != INF){
		make_tag_min(lchild,t[root].tag_min);
		make_tag_min(rchild,t[root].tag_min);
	}
	t[root].tag_add = 0;t[root].tag_max = -INF;t[root].tag_min = INF;
}

void build(int root,int l,int r){
	if(l == r){
		t[root].sum = t[root].Max = t[root].Min = a[l];
		t[root].se_max = t[root].tag_max = -INF;t[root].se_min = t[root].tag_min = INF;
		t[root].cnt_max = t[root].cnt_min = 1;
		return;
	}
	build(lchild,l,mid);
	build(rchild,mid + 1,r);
	push_up(root);
}

void update_sum(int root,int l,int r,int L,int R,int v){
	if(out_range(l,r,L,R))
		return;
	if(in_range(l,r,L,R)){
		make_tag_add(root,len(l,r),v);
		return;
	}
	push_down(root,l,r);
	update_sum(lchild,l,mid,L,R,v);
	update_sum(rchild,mid + 1,r,L,R,v);
	push_up(root);
}
void update_max(int root,int l,int r,int L,int R,int v){
	if(out_range(l,r,L,R) || v <= t[root].Min)
		return;
	if(in_range(l,r,L,R) && t[root].se_min > v){
		make_tag_max(root,v);
		return;
	}
	push_down(root,l,r);
	update_max(lchild,l,mid,L,R,v);
	update_max(rchild,mid + 1,r,L,R,v);
	push_up(root);
}
void update_min(int root,int l,int r,int L,int R,int v){
	if(out_range(l,r,L,R) || v >= t[root].Max)
		return;
	if(in_range(l,r,L,R) && t[root].se_max < v){
		make_tag_min(root,v);
		return;
	}
	push_down(root,l,r);
	update_min(lchild,l,mid,L,R,v);
	update_min(rchild,mid + 1,r,L,R,v);
	push_up(root);
}

int query_sum(int root,int l,int r,int L,int R){
	if(out_range(l,r,L,R))
		return 0;
	if(in_range(l,r,L,R))
		return t[root].sum;
	push_down(root,l,r);
	return query_sum(lchild,l,mid,L,R) + query_sum(rchild,mid + 1,r,L,R);
}
int query_max(int root,int l,int r,int L,int R){
	if(out_range(l,r,L,R))
		return -INF;
	if(in_range(l,r,L,R))
		return t[root].Max;
	push_down(root,l,r);
	return max(query_max(lchild,l,mid,L,R),query_max(rchild,mid + 1,r,L,R));
}
int query_min(int root,int l,int r,int L,int R){
	if(out_range(l,r,L,R))
		return INF;
	if(in_range(l,r,L,R))
		return t[root].Min;
	push_down(root,l,r);
	return min(query_min(lchild,l,mid,L,R),query_min(rchild,mid + 1,r,L,R));
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];
	build(1,1,n);
	cin >> m;
	while(m--){
		int op,l,r,v;
		cin >> op >> l >> r;
		if(op <= 3)
			cin >> v;
		if(op == 1)
			update_sum(1,1,n,l,r,v);
		else if(op == 2)
			update_max(1,1,n,l,r,v);
		else if(op == 3)
			update_min(1,1,n,l,r,v);
		else if(op == 4)
			cout << query_sum(1,1,n,l,r) << '\n';
		else if(op == 5)
			cout << query_max(1,1,n,l,r) << '\n';
		else if(op == 6)
			cout << query_min(1,1,n,l,r) << '\n';
	}
	return 0;
}
2024/9/23 13:44
加载中...