样例已过但爆零
#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;
}