洛谷 P1253 扶苏的问题
题意
区间设置某值 , 区间加 , 区间查询最值
思路
对应设置两个懒标记 , 抹平与添加
如果当前被抹平过 , 那么 \(add\) 时只要加抹平后值即可
如果没有抹平过 , \(add\) 正常加
不管有没有添加过 , 抹平时一律归零
需要注意在push_down时 , 在未抹平情况下 , 仍然需要对左右子树的抹平情况判断 , 从而确定添加到哪
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
int ans = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans * f;
}
const int N = 1e6+10;
int a[N];
struct Node {
int l,r,val,add;
bool f;
};
Node tr[N<<2];
inline void push_up(int p) {
tr[p].val = max(tr[p*2].val,tr[p*2+1].val);
return ;
}
void build(int p,int l,int r) {
tr[p] = {l,r,a[l],0,false};
if (l==r) {
return ;
}
int mid = (l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
push_up(p);
}
void push_down(int p) {
if (tr[p].f) {
tr[p*2].f = true;
tr[p*2+1].f = true;
tr[p].f = false;
tr[p*2].val = tr[p].val;
tr[p*2+1].val = tr[p].val;
tr[p*2].add = 0;
tr[p*2+1].add = 0;
}
else {
if (!tr[p*2].f) {
tr[p*2].add += tr[p].add;
}
tr[p*2].val += tr[p].add;
if (!tr[p*2+1].f) {
tr[p*2+1].add += tr[p].add;
}
tr[p*2+1].val += tr[p].add;
tr[p].add = 0;
}
}
void add(int p,int l,int r,int k) {
if (tr[p].r <= r && tr[p].l >= l) {
tr[p].val += k;
if (!tr[p].f)
tr[p].add += k;
return ;
}
push_down(p);
int mid = tr[p].l + tr[p].r >> 1;
if (l <= mid)
add(p*2,l,r,k);
if (r > mid)
add(p*2+1,l, r, k);
push_up(p);
}
void moping(int p,int l,int r,int k) {
if (tr[p].l >= l && tr[p].r <= r) {
tr[p].val = k;
tr[p].f = true;
tr[p].add = 0;
return ;
}
push_down(p);
int mid = tr[p].l + tr[p].r >> 1;
if (l <= mid)
moping(p*2,l,r,k);
if (r > mid)
moping(p*2+1,l, r, k);
push_up(p);
}
int query(int p,int l,int r) {
if (tr[p].l>=l && tr[p].r <= r)
return tr[p].val;
push_down(p);
int mid = tr[p].l + tr[p].r >> 1;
int ans = -1e18-5;
if (l <= mid)
ans = max(ans, query(p*2,l,r));
if (r > mid)
ans = max(ans, query(p*2+1,l,r));
return ans;
}
signed main() {
int n =read(),m=read();
for (int i = 1; i<= n; i++) {
a[i]= read();
}
build(1,1,n);
int op,x,y,k;
while (m--) {
op =read();
if (op==1) {
x = read(), y =read(),k = read();
moping(1,x,y,k);
}
else if (op == 2) {
x =read(),y=read(),k=read();
add(1,x,y,k);
}
else {
x= read(),y =read();
cout<<query(1,x,y)<<"\n";
}
}
return 0;
}

浙公网安备 33010602011771号