P1253

[yLOI2018] 扶苏的问题

题目描述

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

  1. 给定区间 \([l, r]\),将区间内每个数都修改为 \(x\)
  2. 给定区间 \([l, r]\),将区间内每个数都加上 \(x\)
  3. 给定区间 \([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;
}
posted @ 2023-01-20 15:46  PKU_IMCOMING  阅读(12)  评论(0)    收藏  举报