P1253 [yLOI2018] 扶苏的问题
题面
给定一个长度为 的序列 ,要求支持如下三个操作:
- 给定区间 ,将区间内每个数都修改为 。
- 给定区间 ,将区间内每个数都加上 。
- 给定区间 ,求区间内的最大值。
输入格式
第一行是两个整数,依次表示序列的长度 和操作的个数 。
第二行有 个整数,第 个整数表示序列中的第 个数 。
接下来 行,每行表示一个操作。每行首先有一个整数 ,表示操作的类型。
- 若 ,则接下来有三个整数 ,表示将区间 内的每个数都修改为 。
- 若 ,则接下来有三个整数 ,表示将区间 内的每个数都加上 。
- 若 ,则接下来有两个整数 ,表示查询区间 内的最大值。
输出格式
对于每个 的操作,输出一行一个整数表示答案。
数据规模与约定
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,,,,。
提示
请注意大量数据读入对程序效率造成的影响。
思路
这道题太坑了。
用线段树维护区间 ,以及区间赋值与区间加的 。
记得在赋值的时候清空 add
标记!(这个我 分咕了很久)。
代码
其实我觉得提示中的信息没有一点用。
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】