0
点赞
收藏
分享

微信扫一扫

P1253 [yLOI2018] 扶苏的问题 (线段树)

脱下愤怒的小裤衩 2022-05-02 阅读 37

原题链接:[yLOI2018] 扶苏的问题 - 洛谷

 

 

AC代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for(int i = n; i >= 1; ++i)

using namespace std;
const double pi = acos(-1.0);

const int MAXN = 1e6 + 10;
ll n,m;
ll a[MAXN];

ll tree[MAXN<<2], add[MAXN<<2], upd[MAXN<<2];
inline void pushup(ll rt) { tree[rt] = max(tree[rt<<1] , tree[rt<<1|1]); }
inline void downupd(ll rt){
        if(upd[rt] != INF){
		upd[rt<<1] = upd[rt<<1|1] = upd[rt];
		tree[rt << 1] = tree[rt << 1 | 1] = upd[rt];
		add[rt << 1] = add[rt << 1 | 1] = 0;
		upd[rt] = INF;
        }
}

inline void downadd(ll rt){
	    if(add[rt]){
		add[rt<<1] += add[rt];
		tree[rt<<1] += add[rt];
		add[rt<<1|1] += add[rt];
        tree[rt<<1|1] += add[rt];
        add[rt] = 0;
	    }
}

inline void build(ll rt,ll l,ll r){
	upd[rt] = INF;
	if(l == r){
		tree[rt] = a[l];
		return ;
	}
	ll mid = (l+r)>>1;
	build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
	pushup(rt);
}

inline void update(ll rt,ll l,ll r,ll L,ll R,ll val){
	if(l >= L && r <= R){ //区间更新
		tree[rt] = val;
		upd[rt] = val;
		add[rt] = 0;
		return;
	}
	downupd(rt);
	downadd(rt);
	ll mid = (l+r)>>1;
	if(L <= mid) update(rt<<1,l,mid,L,R,val);
	if(R > mid) update(rt<<1|1,mid+1,r,L,R,val);
	pushup(rt);
}

inline void Add(ll rt,ll l,ll r,ll L,ll R,ll val){ //加x
	if(l >= L && r <= R){ //区间更新
		tree[rt] += val;
		add[rt] += val;
		return;
	}
	downupd(rt);
	downadd(rt);
	ll mid = (l+r)>>1;
	if(L <= mid) Add(rt<<1,l,mid,L,R,val);
	if(R > mid) Add(rt<<1|1,mid+1,r,L,R,val);
	pushup(rt);
}

ll query(ll rt,ll l,ll r,ll L,ll R){
	if(l >= L && r <= R) return tree[rt];
	downupd(rt);
	downadd(rt);
	ll mid = (l + r) >> 1;
	ll ans = -1e16;
	if(L <= mid) ans = max(ans, query(rt<<1,l,mid,L,R));
	if(R > mid) ans = max(ans, query(rt<<1|1,mid+1,r,L,R));
	return ans;
}

int main(){
	scanf("%lld %lld", &n, &m);
	rep(i, n) scanf("%lld", &a[i]);
	build(1,1,n);
	while(m--){
		int p;
		ll l, r, x;
		scanf("%d", &p);
		if(p == 1){
		scanf("%lld %lld %lld", &l, &r, &x);
		update(1, 1, n, l, r, x);
		}
		else if(p == 2)
        {
        scanf("%lld %lld %lld", &l, &r, &x);
        Add(1, 1, n, l, r, x);
        }
        else{
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", query(1, 1, n, l, r));
        }
	}
	return 0;
}

参考: 【洛谷P1253】扶苏的问题【线段树】_Ayane.的博客-CSDN博客

举报

相关推荐

0 条评论