最大值线段树 P1253 球求拉 玄关
  • 板块学术版
  • 楼主a_blue_fool
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/9/26 14:04
  • 上次更新2024/9/26 19:06:28
查看原帖
最大值线段树 P1253 球求拉 玄关
1046223
a_blue_fool楼主2024/9/26 14:04
#include <iostream>
#include <cstdio>

#define MAXN 1000005
#define ll long long

using namespace std;

struct node{
	ll sum, tag_add, maxn, k;
}tree[MAXN*4];

ll n, q, op, l, r, x;
ll a[MAXN];

inline ll ls(ll x){
	return x*2;
}

inline ll rs(ll x){
	return x*2+1;
}

ll max(ll a, ll b){
	return a>b?a:b;
}

void push_up(ll x){
	tree[x].sum=tree[ls(x)].sum+tree[rs(x)].sum;
	tree[x].maxn=max(tree[ls(x)].maxn, tree[rs(x)].maxn);
	return;
}

void clear(ll x){
	tree[x].sum=tree[x].k=tree[x].maxn=tree[x].tag_add=0;
}

void push_down(ll x, ll l, ll r){
	ll mid=(l+r)/2;
	
	if(tree[x].k){
		clear(ls(x)); 
		clear(rs(x));
		tree[ls(x)].k = tree[rs(x)].k = tree[x].k;
		tree[ls(x)].sum = tree[rs(x)].sum = tree[x].k;
		tree[x].k=0;
	}
	
	tree[ls(x)].sum += tree[x].tag_add * (mid-l+1);
	tree[ls(x)].tag_add += tree[x].tag_add;
	tree[ls(x)].maxn += tree[x].tag_add;
	
	tree[rs(x)].sum+=tree[x].tag_add*(r-mid);
	tree[rs(x)].tag_add+=tree[x].tag_add;
	tree[rs(x)].maxn+=tree[x].tag_add;

	tree[x].tag_add = 0;
	
	return;
}

void build(ll x, ll l, ll r){
	if(l>r)return;
	
	if(l==r){
		tree[x].maxn=tree[x].sum=a[l];
		return;
	}
	
	ll mid=(l+r)/2;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	push_up(x);
	
	return;
}

void change(ll x, ll l, ll r, ll L, ll R, ll k){
	if(L<=l&&r<=R){
		clear(x);
		tree[x].k=k;
		tree[x].maxn=k;
		tree[x].sum=k;
		return;
	}
	
	ll mid=(l+r)/2;
	push_down(x,l,r);
	if(L<=mid)change(ls(x), l, mid, L, R, k);
	if(R>mid)change(rs(x), mid+1, r, L, R, k);
	
	return;
}

void add(ll x, ll l, ll r, ll L, ll R, ll k){
	if(L<=l&&r<=R){
		tree[x].sum+=(r-l+1)*k;
		tree[x].maxn+=k;
		return;
	}
	
	ll mid=(l+r)/2;
	push_down(x,l,r);
	if(L<=mid)add(ls(x), l, mid, L, R, k);
	if(R>mid)add(rs(x), mid+1, r, L, R, k);
	
	return;
}

ll maxn(ll x, ll l, ll r, ll L, ll R){
	if(L<=l&&r<=R)
		return tree[x].maxn;
	
	ll mid=(l+r)/2;
	push_down(x,l,r);
	ll ans=-1e18;
	if(L<=mid)ans=max(maxn(ls(x), l, mid, L, R), ans);
	if(R>mid)ans=max(maxn(rs(x), mid+1, r, L, R), ans);
	
	return ans;	
}

int main(){
	scanf("%lld%lld", &n, &q);
	for(ll i=1; i<=n; i++)scanf("%lld", &a[i]);
	
	build(1,l,r);
	
	for(ll i=1; i<=q; i++){
		scanf("%lld", &op);
		if(op==1){
			scanf("%lld%lld%lld", &l, &r, &x);
			change(1, 1, n, l, r, x);
		}
		else if(op==2){
			scanf("%lld%lld%lld", &l, &r, &x);
			add(1, 1, n, l, r, x);
		}
		else{
			scanf("%lld%lld", &l, &r);
			printf("%lld\n", maxn(1, 1, n, l, r));
		}
	}
	
	return 0;
}
2024/9/26 14:04
加载中...