P1253 [yLOI2018] 扶苏的问题

题面

给定一个长度为 n 的序列 a,要求支持如下三个操作:

  1. 给定区间 [l,r],将区间内每个数都修改为 x
  2. 给定区间 [l,r],将区间内每个数都加上 x
  3. 给定区间 [l,r],求区间内的最大值。

输入格式

第一行是两个整数,依次表示序列的长度 n 和操作的个数 q
第二行有 n 个整数,第 i 个整数表示序列中的第 i 个数 ai
接下来 q 行,每行表示一个操作。每行首先有一个整数 op,表示操作的类型。

  • op=1,则接下来有三个整数 l,r,x,表示将区间 [l,r] 内的每个数都修改为 x
  • op=2,则接下来有三个整数 l,r,x,表示将区间 [l,r] 内的每个数都加上 x
  • op=3,则接下来有两个整数 l,r,表示查询区间 [l,r] 内的最大值。

输出格式

对于每个 op=3 的操作,输出一行一个整数表示答案。

数据规模与约定

  • 对于 10% 的数据,n=q=1
  • 对于 40% 的数据,n,q103
  • 对于 50% 的数据,0ai,x104
  • 对于 60% 的数据,op1
  • 对于 90% 的数据,n,q105
  • 对于 100% 的数据,1n,q1061l,rnop{1,2,3}|ai|,|x|109

提示

请注意大量数据读入对程序效率造成的影响。

思路

这道题太坑了。

用线段树维护区间 max,以及区间赋值与区间加的 lazy-tag

记得在赋值的时候清空 add 标记!(这个我 60 分咕了很久)。

代码

其实我觉得提示中的信息没有一点用。

#include <bits/stdc++.h>
#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
#define int long long
using namespace std;

struct node{
	int maxv,add,cov;
	node(){
		this->cov = LLONG_MIN;
		this->add = 0;
	}
} t[4000005];
int a[1000005];
int n,q;

inline void pushup(int i){
	t[i].maxv=max(t[ls].maxv,t[rs].maxv);
}

void build(int i,int l,int r){
	if(l==r){
		t[i].maxv=a[l];
	}
	else{
		build(ls,l,mid);
		build(rs,mid+1,r);
		pushup(i);
	}
}

void pushdown(int i){
    if(t[i].cov!=LLONG_MIN){
		t[ls].maxv=t[rs].maxv=t[ls].cov=t[rs].cov=t[i].cov;
		//t[ls].cov+=t[ls].add;
		//t[rs].cov+=t[rs].add;
		t[ls].add=t[rs].add=0;
		t[i].cov=LLONG_MIN;
	}
	if(t[i].add){
		t[ls].add+=t[i].add;
		t[rs].add+=t[i].add;
		t[ls].maxv+=t[i].add;
		t[rs].maxv+=t[i].add;
		t[i].add=0;
	}
}

void add(int ql,int qr,int v,int i,int l,int r){
	if(ql<=l&&r<=qr){
		t[i].maxv+=v;
		t[i].add+=v;
		return;
	}
	pushdown(i);
	if(ql<=mid){
		add(ql,qr,v,ls,l,mid);
	}
	if(mid<qr){
		add(ql,qr,v,rs,mid+1,r);
	}
	pushup(i);
}

void cover(int ql,int qr,int v,int i,int l,int r){
	if(ql<=l&&r<=qr){
		t[i].maxv=v;
		t[i].cov=v;
		t[i].add=0;
		return;
	}
	pushdown(i);
	if(ql<=mid){
		cover(ql,qr,v,ls,l,mid);
	}
	if(mid<qr){
		cover(ql,qr,v,rs,mid+1,r);
	}
	pushup(i);
}

int query(int ql,int qr,int i,int l,int r){
	if(ql<=l&&r<=qr){
		return t[i].maxv;
	}
	pushdown(i);
	int result=LLONG_MIN;
	if(ql<=mid){
		result=max(result,query(ql,qr,ls,l,mid));
	}
	if(mid<qr){
		result=max(result,query(ql,qr,rs,mid+1,r));
	}
	return result;
}

signed main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,1,n);
	while(q--){
		int op,l,r,x;
		cin>>op;
		if(op==2){
			cin>>l>>r>>x;
			add(l,r,x,1,1,n);
		}
		if(op==1){
			cin>>l>>r>>x;
			cover(l,r,x,1,1,n);
		}
		if(op==3){
			cin>>l>>r;
			cout<<query(l,r,1,1,n)<<endl;
		}
	}
	return 0;
}

Record

posted @   蒟蒻xiezheyuan  阅读(114)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示