首页 > 其他分享 >《扶苏的问题》题解

《扶苏的问题》题解

时间:2024-06-02 11:33:25浏览次数:25  
标签:pr 题解 ll mid 扶苏 问题 tag push change

《扶苏的问题》题解

原题传送门:P1253 扶苏的问题

PS:请先阅读完题面,在继续观看

题意概述:

​ 对于给定的数列 \({a_1,a_2,a_3……a_n}\) ,进行以下三个操作:

​ 1.change 将区间 \([L,R]\) 的值修改为 \(X\) ;

​ 2.add 将区间 \([L,R]\) 的值加上为 \(D\) ;

​ 3.query 查询区间 \([L,R]\) 的最大值;

分析:

对于本题,为追求最佳时间复杂度,我们将使用两个懒标记,分别记录 \(change\) 和 \(add\) 标记。

对于改与加标记这两个标记,我们可以发现改标记的优先度要大于加标记(都覆盖了,你还加啥呀),于是对于 \(push -down\) 操作来说,优先下放改标记。同时,在进行改标记的添加时,对于将要被打上改标记的线段,其加标记将失去作用,即归零;

AC代码详解

#include<bits/stdc++.h>
#define ll long long 
#define seq(q,w,e) for(int q=w;q<=e;q++)
using namespace std;
const ll maxn=1e6+10;
const ll maxx=4e6+10;
const ll inf=2e15;                                 //首先,inf太小会出错
ll a[maxn],tree[maxx],tag1[maxx],tag2[maxx];       //tag1为加标记,tag2为改标记
ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
void push_up(ll p){
	tree[p]=max(tree[ls(p)],tree[rs(p)]);          //求最大值的线段树维护
}
void build_tree(ll p,ll pl,ll pr){
	tag1[p]=0;tag2[p]=-inf;                        //其次,tag1,tag2不赋初值也会出错
	if(pl==pr){
		tree[p]=a[pl];
		return;
	}
	ll mid=(pl+pr)>>1;
	build_tree(ls(p),pl,mid);
	build_tree(rs(p),mid+1,pr);
	push_up(p);
}
void add_tag(ll p,ll d){
	tree[p]+=d;
	tag1[p]+=d;
}
void change_tag(ll p,ll x){
	tree[p]=x;                                     //既然是修改,当然是直接覆盖啦
	tag2[p]=x;                                     
	tag1[p]=0;                                     //再来,tag1不归零还会出错
}
void push_down(ll p){                              //先加后改,也会出错  
	if(tag2[p]!=-inf){                             //注意,tag2数组的初始值为-inf
		change_tag(ls(p),tag2[p]); 
		change_tag(rs(p),tag2[p]);
		tag2[p]=-inf;                              //用完记得还原
	}
	if(tag1[p]){
		add_tag(ls(p),tag1[p]);
		add_tag(rs(p),tag1[p]);
		tag1[p]=0;
	} 
}
void change(ll l,ll r,ll p,ll pl,ll pr,ll x){
	if(l<=pl&&r>=pr){
		change_tag(p,x);
		return;
	}
	push_down(p);                                  //别忘了下传标记,下同
	ll mid=(pl+pr)>>1;
	if(l<=mid) change(l,r,ls(p),pl,mid,x);
	if(r>mid) change(l,r,rs(p),mid+1,pr,x);
	push_up(p);                                    //别忘了维护树,下同
}
void up_data(ll l,ll r,ll p,ll pl,ll pr,ll d){
	if(l<=pl&&r>=pr){
		add_tag(p,d);
		return;
	}
	push_down(p);
	ll mid=(pl+pr)>>1;
	if(l<=mid) up_data(l,r,ls(p),pl,mid,d);
	if(r>mid) up_data(l,r,rs(p),mid+1,pr,d);
	push_up(p);
}
ll query(ll l,ll r,ll p,ll pl,ll pr){
	if(l<=pl&&r>=pr) 
		return tree[p];
	push_down(p);
	ll mid=(pl+pr)>>1,res=-inf;
	if(l<=mid) res=query(l,r,ls(p),pl,mid);
	if(r>mid) res=max(res,query(l,r,rs(p),mid+1,pr));
	return res;
}
ll n,m,op;
ll l,r,sum;
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	seq(i,1,n){
		cin>>a[i];
	}
	build_tree(1,1,n);                             //不建树更会报错
	seq(i,1,m){
		cin>>op>>l>>r;
		if(op==1){
			cin>>sum;
			change(l,r,1,1,n,sum);
		}
		if(op==2){
			cin>>sum;
			up_data(l,r,1,1,n,sum);
		}
		if(op==3){
			cout<<query(l,r,1,1,n)<<"\n";
		}
	}
	return 0;
}

总的来说,是一道不错的线段树版子题,不得不说,做完后对线段树的理解加深了许多。

标签:pr,题解,ll,mid,扶苏,问题,tag,push,change
From: https://www.cnblogs.com/adsd45666/p/18226912

相关文章

  • WSL2--DNS解析问题解决
    1.问题xurong@DESKTOP-SOE9MG1:~/.ssh$sudoaptupdateIgn:1http://security.ubuntu.com/ubuntunoble-securityInReleaseIgn:2http://archive.ubuntu.com/ubuntunobleInReleaseIgn:3http://archive.ubuntu.com/ubuntunoble-updatesInReleaseIgn:4http://archive......
  • Qt for Android 轻松解决编译器无法被识别问题!!
        相信很多小伙伴,也碰到过这种问题。明明下载Qt时,勾选了安卓组件,JDK,NDK、SDK都配置成功,但还是没有安卓编译器,或者是编译器前面有黄色感叹号,无法使用编译器。下面有解决办法。    解决方法:        1、Qt缓存导致(解决大部分问题):        ......
  • vmicres.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个vmicres.dll文件(挑选合适的版本文件)把它放......
  • vdsutil.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个vdsutil.dll文件(挑选合适的版本文件)把它放......
  • 《计算机网络微课堂》实验13 静态路由配置错误导致的路由环路问题
    下面我们来进行一个仿真实验,本仿真实验的目的在于验证静态路由配置错误所导致的路由环路问题。我已经在软件中构建好了我们理论课讲解时所用到的网络拓扑,并且给网络中的各设备都配置了相应的IP地址和地址掩码。对于网络中的各个主机,我还为他们指定了默认网关,对于网络中的各个......
  • linux 安装字体解决JAVA图形中文乱码问题
    1、在C:\Windows\Fonts\找到想要安装到linux的字体;如微软雅黑字体,它们可能的文件包括:2、将相关字体文件复制到指定文件夹“/usr/share/fonts/”3、执行字体安装:cd/usr/share/fonts/mkfontscalemkfontdir如果提示 mkfontscale:commandnotfound,需自行安装 yuminstallm......
  • pdf转word/text后换行问题
    pdf转word/text后换行问题pdf转为word/text,或者从pdf复制一段文字,这段文字有很多换行(其实就相当于一行一段):野史里说,楚汉争霸时期,高祖刘邦大败。薄氏还是个姑娘的时候叫薄姬,逃难的时候占领了一个无人居住的民宅。忽然有一天看见一个浑身是血,穿着盔甲拿着兵器的男人闯进了自......
  • uniapp开发APP遇到的问题
    图标变成了undefined原因:设置prefix时,在非nvue环境下,需u-input才有效。//旧版<u--inputplaceholder="请输入用户名"type="text"> <templateslot="prefix"> <viewclass="solts"> <viewstyle="padding-top:6upx&qu......
  • Navicat, PDManer,PyMySQL模块,SQL注入问题,PyMySQL进阶之主动提交事务
    ⅠNavicat【一】Navicat介绍Navicat可以充当很多数据库软件的客户端提供了图形化界面能够让我们更加快速的操作数据库【1】介绍Navicat是一款功能强大且广泛使用的数据库管理工具,可用于连接和管理多种数据库系统,如MySQL、MariaDB、Oracle、PostgreSQL等。本文将详细......
  • CF1961E Turtle and Intersected Segments 题解
    题目链接点击打开链接题目解法不是,我这咋不会做/fn边数很多的最小生成树有一个方法是\(boruvka\),但这个处理完全图的比较方便另一个方法是用到一个\(trick\):连出的图中的环,可以删去最长边扫描线是容易想到的,主要是如何把连的边数缩减到合理的范围内考虑扫描线到当前时刻......