首页 > 其他分享 >[动态开点の线段树]

[动态开点の线段树]

时间:2024-07-30 16:30:03浏览次数:7  
标签:RS int 线段 tree 动态 sum define

动态开点の线段树

因为静态建点线段树消耗的空间太大了,需要开四倍空间,但是动态开点就可以大大降低所使用的空间,远小于四倍

具体思想和线段树没有区别只是将\(k<<1\)换成了\(LS(k)\),将\(k<<1|1\)换成了\(RS(k)\),(具体开多少空间不是很能确定

#include <cstdio>
#include <iostream>
#define LS(x) tree[x].ls
#define RS(x) tree[x].rs
#define L(x) tree[x].l
#define R(x) tree[x].r
typedef long long LL;
using namespace std;
const int maxn = 2e5+6;
int n,m,ncnt = 1;
LL ans = 0;
struct Tree{
	int l,r,ls,rs;
	LL sum,tag;
}tree[maxn];

void build(int p,int v,int k)
{
	if(L(k) == R(k))
	{
		tree[k].sum = v;
		return ;
	}
	int mid = L(k) + R(k) >> 1;
	if(p <= mid)
	{
		if(!LS(k)) LS(k) = ++ ncnt;
		L(LS(k)) = L(k);
		R(LS(k)) = mid;
		build(p,v,LS(k));
	}
	else {
		if(!RS(k)) RS(k) = ++ ncnt;
		L(RS(k)) = mid + 1;
		R(RS(k)) = R(k);
		build(p,v,RS(k));
	}
	tree[k].sum = tree[LS(k)].sum + tree[RS(k)].sum;
	return ; 
}

void down(int k)
{
	tree[LS(k)].sum += (R(LS(k)) - L(LS(k)) + 1) * tree[k].tag;
	tree[RS(k)].sum += (R(RS(k)) - L(RS(k)) + 1) * tree[k].tag;
	tree[LS(k)].tag += tree[k].tag;
	tree[RS(k)].tag += tree[k].tag;
	tree[k].tag = 0;
	return ;
}

void update(int l,int r,int v,int k)
{
	if(l <= L(k) && R(k) <= r)
	{
		tree[k].sum += (R(k) - L(k) + 1) * v;
		tree[k].tag += v;
		return ;
	}
	if(tree[k].tag) down(k);
	int mid = L(k) + R(k) >> 1;
	if(l <= mid) update(l,r,v,LS(k));
	if(r > mid) update(l,r,v,RS(k));
	tree[k].sum = tree[LS(k)].sum + tree[RS(k)].sum;
	return ;
}

void query(int l,int r,int k)
{
	if(l <= L(k) && R(k) <= r)
	{
		ans += tree[k].sum;
		return ;
	}
	if(tree[k].tag) down(k);
	int mid = L(k) + R(k) >> 1;
	if(l <= mid) query(l,r,LS(k));
	if(r > mid) query(l,r,RS(k));
	return ;
}

int main()
{
	scanf("%d%d",&n,&m);
	L(1) = 1,R(1) = n;
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		build(i,x,1);
	}
	while(m --)
	{
		int op;
		scanf("%d",&op);
		if(op == 1)
		{
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			update(x,y,z,1);
		}
		else {
			int x,y; ans = 0;
			scanf("%d%d",&x,&y);
			query(x,y,1);
			printf("%lld\n",ans);
		} 
	}
	return 0;
}

标签:RS,int,线段,tree,动态,sum,define
From: https://www.cnblogs.com/-Wind-/p/18332726

相关文章

  • 动态内存管理
    ⽬录1.为什么要有动态内存分配2.malloc和free3.calloc和realloc4.常⻅的动态内存的错误5.动态内存经典笔试题分析6.柔性数组7.总结C/C++中程序内存区域划分正⽂开始1.为什么要有动态内存分配我们已经掌握的......
  • EasyExcel数据导出实现、动态表头生成、SpringBoot3框架
    1、引入EasyExcel依赖<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>2、定义ExcelModel表单模型publicclassExcelMod......
  • OSPF动态路由协议实验
    首先地址划分一个骨干网段分成三个,r1,r2,r5三个环回网段 ,总共要四个网段192.168.1.0/24192.168.1.0/26---骨干网段192.168.1.0/28192.168.1.16/28192.168.1.32/28备用192.168.1.64/28192.168.1.64/26---r1环回192.168.1.128/26---r2环回192.168.1.192/26---r3环回......
  • 李超线段树
    李超线段树用途:在平面上插入一个线段或直线,求出与\(x=a\)相交的线段中纵坐标最大的线段编号。【模板】李超线段树/[HEOI2013]Segment将任务转化成插入一个定义域为\([l,r]\)的一次函数给定\(k\),求定义域包含\(k\)的所有一次函数中,在\(x=k\)处取值最大的那个,如果有多个......
  • 动态A/B测试:在Mojo模型中实现模型比较的智能策略
    动态A/B测试:在Mojo模型中实现模型比较的智能策略引言在机器学习模型的开发和部署过程中,A/B测试是一种关键的方法,用于比较不同模型版本或不同算法的性能。Mojo模型,通常指的是H2O.ai框架中导出的模型,支持在多种环境中运行预测。实现Mojo模型的自定义A/B测试不仅可以帮助我们......
  • 小一保姆级 python三大核心多态、抽象类、动态添加内容详解
    一.多态多态是面向对象编程中的一个核心概念,它允许一个接口被多个数据类型实现。这意味着,即使多个类具有不同的内部实现,它们也可以共享一个公共接口。多态的实现通常依赖于继承和方法重写。继承:子类继承父类的属性和方法。方法重写:子类重写父类中的方法,以提供特定的实现。......
  • htop [非内部命令]一个互动的进程查看器,可以动态观察系统进程状况
    htop[非内部命令]一个互动的进程查看器,可以动态观察系统进程状况补充说明htop命令是Linux系统中的一个互动的进程查看器,一个文本模式的应用程序(在控制台或者X终端中),需要ncurses。与Linux传统的top相比,htop更加人性化。它可让用户交互式操作,支持颜色主题,可横向或纵向滚动浏......
  • 深入理解Java中的反射和动态代理
    深入理解Java中的反射和动态代理大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来深入探讨Java中的反射和动态代理。反射和动态代理是Java中非常强大的技术,能够极大地增强代码的灵活性和动态性。我们将详细介绍它们的基本概念、用法以及一些实际......
  • 函数 动态参数
    #固定参数+动态位置参数defmy_function(a,b,*args):print(a)print(b)print(args)my_function(1,'c',1,2,3,4,5,6)#输出#1#固定位第一个占位符#c#固定位第二个占位符#(1,2,3,4,5,6)#剩下的部分#可变关键词参数defmy_funciton2(a,b,......
  • C#动态计算字符串中的表达式
    最近遇到一个需要计算字符串中表达式的需求,需要从字符串公式中动态计算结果。类似下面这样1stringexpression="Age*0.2+Height*0.1+log4"; 使用DataTable.Compute函数一开始找的是下面这种方法,但是不能计算对数1usingSystem.Data;23DataTabledt=ne......