P1253
[yLOI2018] 扶苏的问题
题目描述
给定一个长度为 \(n\) 的序列 \(a\),要求支持如下三个操作:
- 给定区间 \([l, r]\),将区间内每个数都修改为 \(x\)。
- 给定区间 \([l, r]\),将区间内每个数都加上 \(x\)。
- 给定区间 \([l, r]\),求区间内的最大值。
输入格式
第一行是两个整数,依次表示序列的长度 \(n\) 和操作的个数 \(q\)。
第二行有 \(n\) 个整数,第 \(i\) 个整数表示序列中的第 \(i\) 个数 \(a_i\)。
接下来 \(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\) 的操作,输出一行一个整数表示答案。
样例 #1
样例输入 #1
6 6
1 1 4 5 1 4
1 1 2 6
2 3 4 2
3 1 4
3 2 3
1 1 6 -1
3 1 6
样例输出 #1
7
6
-1
样例 #2
样例输入 #2
4 4
10 4 -3 -7
1 1 3 0
2 3 4 -4
1 2 4 -9
3 1 4
样例输出 #2
0
提示
数据规模与约定
对于 \(10\%\) 的数据,\(n = q = 1\)。
对于 \(40\%\) 的数据,\(n, q \leq 10^3\)。
对于 \(50\%\) 的数据,\(0 \leq a_i, x \leq 10^4\)。
对于 \(60\%\) 的数据,\(op \neq 1\)。
对于 \(90\%\) 的数据,\(n, q \leq 10^5\)。
对于 \(100\%\) 的数据,\(1 \leq n, q \leq 10^6\),\(1 \leq l, r \leq n\),\(op \in \{1, 2, 3\}\),\(|a_i|, |x| \leq 10^9\)。
区间修改 推平 查询操作
加深对pushdown的认识
像这种就分开modify pushdown 合在一起容易写错
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=10000000000000000;
int n,q,a[1000005],op,l,r,x;
struct tree{
int l,r,maxx,add,pt;
}tr[1000005*4];
void pushup(int p){tr[p].maxx=max(tr[p<<1].maxx,tr[p<<1|1].maxx);}
void build(int p,int l,int r)
{
tr[p].l=l,tr[p].r=r;tr[p].add=0,tr[p].pt=-inf;
if(l==r){tr[p].maxx=a[l];return ;}
int mid=(l+r)>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);
pushup(p);
}
void pushdown1(int p)
{
if(tr[p].pt!=-inf)
{
tr[p<<1].add=tr[p<<1|1].add=0;
tr[p<<1].maxx=tr[p<<1|1].maxx=tr[p].pt;
tr[p<<1].pt=tr[p<<1|1].pt=tr[p].pt;
tr[p].pt=-inf;
}
}
void pushdown2(int p)
{
if(tr[p].add)
{
pushdown1(p);
tr[p<<1].maxx+=tr[p].add,tr[p<<1|1].maxx+=tr[p].add;
tr[p<<1].add+=tr[p].add,tr[p<<1|1].add+=tr[p].add;
tr[p].add=0;
}
}
void pushdown(int p)
{
pushdown1(p);
pushdown2(p);
}
void modify1(int p,int l,int r,int pt)
{
if(l<=tr[p].l&&r>=tr[p].r)
{
tr[p].add=0;
tr[p].maxx=pt,tr[p].pt=pt;
return ;
}
pushdown(p);
int mid=(tr[p].l+tr[p].r)>>1;
if(l<=mid)modify1(p<<1,l,r,pt);
if(r>mid)modify1(p<<1|1,l,r,pt);
pushup(p);
}
void modify2(int p,int l,int r,int add)
{
if(l<=tr[p].l&&r>=tr[p].r)
{
tr[p].add+=add;
tr[p].maxx+=add;
return ;
}
pushdown(p);
int mid=(tr[p].l+tr[p].r)>>1;
if(l<=mid)modify2(p<<1,l,r,add);
if(r>mid)modify2(p<<1|1,l,r,add);
pushup(p);
}
int query(int p,int l,int r)
{
if(l<=tr[p].l&&r>=tr[p].r)return tr[p].maxx;
int maxx=-inf;int mid=(tr[p].l+tr[p].r)>>1;
pushdown(p);
if(l<=mid)maxx=max(maxx,query(p<<1,l,r));
if(r>mid)maxx=max(maxx,query(p<<1|1,l,r));
return maxx;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
// cout<<inf<<"\n\n";
build(1,1,n);
while(q--)
{
cin>>op;
if(op==1)
{
cin>>l>>r>>x;
modify1(1,l,r,x);
}
if(op==2)
{
cin>>l>>r>>x;
modify2(1,l,r,x);
}
if(op==3)
{
cin>>l>>r;
cout<<query(1,l,r)<<"\n";
}
}
return 0;
}
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号