首页 > 其他分享 >线段树1模板 (洛谷p3372)

线段树1模板 (洛谷p3372)

时间:2024-12-25 13:56:33浏览次数:5  
标签:洛谷 int sum mid long down maxn p3372 模板

关键在于创建一个向上返回的函数up,向下查询的同时将父亲sum和add值传给儿子函数down

最后用lazy函数更新sum和add的值

先通过build函数是sum数组完成初始化,然后用adds已经quiey函数完成求解,详细注释见代码

​
#include<iostream>
#include<cstdio>
using namespace std;
int m,n;
const int maxn=100001;
long long arr[maxn];
long long sum[maxn<<2];
long long add[maxn<<2];
void up(int i)//向上返回之后更新sum的值
{
	sum[i]=sum[i<<1]+sum[i<<1|1];
}
void lazy(int i,long long v,int n)//n为线段长度,v为要加入的数,i为当前下标
{
	sum[i]+=v*n;
	add[i]+=v;
}
void down(int i,int ln,int rn)//向下走,一边构建add数组,一边使它清空
{
	if(add[i]!=0){
		lazy(i<<1,add[i],ln);//传入父亲的add[i]值,使儿子的add值继承父亲的add值,之后将父亲的add值清空
		lazy(i<<1|1,add[i],rn);//儿子的数组值比父亲大所以<<1表示儿子,
		add[i]=0;
	}
}
void build(int l,int r,int i)//创建sum数组使之完成初始化
{
	if(l==r) sum[i]=arr[l];//在最底下时arr的值为sum的值
	else{
		int mid=(l+r)>>1;
		build(l,mid,i<<1);
		build(mid+1,r,i<<1|1);
		up(i);//由下而上构建sum数组,构建完之后将
	}
	//add[i]=0;//这一步可以不要,前面没有用上
}
long long query(int jobl, int jobr, int l, int r, int i) {//查询区间内的和
	if (jobl <= l && r <= jobr) {//当前区间被要进行操作的区间完全包含,直接求和;
		return sum[i];
	}
	int mid = (l + r) >> 1;
	down(i, mid - l + 1, r - mid);//向下查询,重新构建儿子的sum,以便等到被完全包含时直接返回sum的值
	long long ans = 0;
	if (jobl <= mid) {//未被完全包含时一直向下查询
		ans += query(jobl, jobr, l, mid, i << 1);//此时ans只需要层层递归加上被完全包住的sum值,同时配合down,将父亲的sum分别分给儿子
	}
	if (jobr > mid) {
		ans += query(jobl, jobr, mid + 1, r, i << 1 | 1);
	}//若未被完全包含,将两边的子节点不断往下查,并且将和加到ans中
	return ans;
}
void adds(int jobl,int jobr,long long jobv,int l,int r,int i)//对范围进行操作
{
	if(jobl<=l&&jobr>=r)//当前区间被要进行操作的区间完全包含
	{
		lazy(i,jobv,r-l+1);
	}
	else{
		int mid=(l+r)>>1;
		down(i,mid-l+1,r-mid);
		if(jobl<=mid)
		{
			adds(jobl,jobr,jobv,l,mid,i<<1);
		}
		if(jobr>mid)
			{
			adds(jobl,jobr,jobv,mid+1,r,i<<1|1);
		}
		up(i);
	}
	
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&arr[i]);
	}
	build(1,n,1);
	int op;
	int jobl,jobr;//要查询的左右界
	long long jobv;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%lld",&jobl,&jobr,&jobv);
			adds(jobl,jobr,jobv,1,n,1);
		}
		else
		{
			scanf("%d%d",&jobl,&jobr);
			printf("%lld\n",query(jobl,jobr,1,n,1));
		}
	}
	return 0;
}

​

标签:洛谷,int,sum,mid,long,down,maxn,p3372,模板
From: https://blog.csdn.net/yj0729/article/details/144558195

相关文章

  • 【模板】拉格朗日插值
    我们没有必要一定要将点值表示转化为系数表示,因为点值表示也可以进行单点求值,而且若点值连续,则还可以线性求值,与转化为系数表示之后没有区别。只需要求值的场合,完全可以只存连续的点值,然后线性的加法、减法、乘法、单点求值,甚至前缀和(线性)、函数复合(平方)。反而更优前途了。我们现......
  • 实验6 模板类、文件I/O和异常处理
    任务1:task1.cpp1Complex.hpp:2#pragmaonce34#include<iostream>5#include<stdexcept>67//声明8////////////////////////////////////////////////////9//复数模板类声明10template<typenameT>11classComplex{......
  • 实验6 模板类,文件I/O及异常处理
    一实验目的练习编写模板函数、模板类,从多态角度理解模板函数和模板类(类型作为参数)体验标准I/O流类、文件I/O流类、字符串I/O流类的用法,能正确使用针对问题场景,使用流类库对I/O数据进行格式化和读、写操作体验异常处理的基础用法,能解释异常处理的机制和流程训练综合应用类的......
  • 4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]
    HTML模板渲染下面是使用Gin框架在Go语言中进行HTML模板渲染的四个示例。每个示例都包含了必要的注释来解释代码的作用。示例1:基本模板渲染packagemainimport( "github.com/gin-gonic/gin" "net/http")funcmain(){ r:=gin.Default() //加载HTML模......
  • 实验6 模板类、文件I/O和异常处理
    task4代码:Vector.hpp1#pragmaonce2#include<iostream>34usingnamespacestd;56template<typenameT>7classVector{8public:9Vector(intn);10Vector(intn,Tvalue);11Vector(constVector<T>&......
  • gesp(三级)(9)洛谷:B3956:[GESP202403 三级] 字母求和
    gesp(三级)(9)洛谷:B3956:[GESP202403三级]字母求和题目描述小杨同学发明了一种新型密码,对于每一个小写英文字母,该小写字母代表了一个正整数,即该字母在字母顺序中的位置,例如字母a代表了正整数1......
  • gesp(三级)(10)洛谷:B3957:[GESP202403 三级] 完全平方数
    gesp(三级)(10)洛谷:B3957:[GESP202403三级]完全平方数题目描述小杨同学有一个包含nnn个非负整数的序列A......
  • DooTask | 提升效率与协作:解锁Dootask任务模板与标签的强大功能
    文章目录前言一、什么是任务模板二、任务模板的优势三、任务标签的优势四、如何使用任务模板与标签五、快速选择并应用模板与标签六、确保任务的细节无误结束语......
  • 实验6 模板类、文件I/O和异常处理
    任务四:#ifndefVECTOR_HPP#defineVECTOR_HPP#include<iostream>#include<stdexcept>template<typenameT>classVector{private:T*elements;size_tnumElements;public:Vector(size_tn=0):numElements(n){if......
  • 模板Tarjan
    Tarjan模板因为每次写Tarjan都会写挂,所以整理了一些模板。主要的证明就跳过了,主要区分不同模板的差异。有向图和无向图有向图和无向图的实现有时候会有区别,因为建出DFS树之后,有向图可能有横叉边,但是无向图不会(显然),所以有些细节需要注意。而且无向图判重边会比较麻烦。无向图......