首页 > 其他分享 >线段树

线段树

时间:2022-10-26 20:22:49浏览次数:60  
标签:int modify LL tr build sum 线段

题目1:(带懒标记的线段树)

给定一个长度为 NN 的数列 AA,以及 MM 条指令,每条指令可能是以下两种之一:

  1. C l r d,表示把 A[l],A[l+1],…,A[r]A[l],A[l+1],…,A[r] 都加上 dd。
  2. Q l r,表示询问数列中第 l∼rl∼r 个数的和。

对于每个询问,输出一个整数表示答案。

题目来源:https://www.acwing.com/problem/content/244/

#include<bits/stdc++.h>
#define LL long long 
using namespace std;

const int N = 1e5+1;
int n,m,w[N];

struct node{
	int l,r;
	LL sum,add;
}tr[4*N];

void pushup(int u){
	tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}

void build(int u,int l,int r){
	if(l==r)
		tr[u]={l,r,w[l],0};
	else{
		tr[u]={l,r};
		int mid = l + r>>1;
		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
		pushup(u);
	}
}

void pushdown(int u){
	if(tr[u].add){
		node &left=tr[u<<1],&right=tr[u<<1|1];
		tr[u<<1].add+=tr[u].add,left.sum+=(LL)(left.r-left.l+1)*tr[u].add;
		tr[u<<1|1].add+=tr[u].add,right.sum+=(LL)(right.r-right.l+1)*tr[u].add;
		tr[u].add=0;
	}
} 

void modify(int u,int l,int r,int d){
	if(tr[u].l>= l and tr[u].r<=r){
		tr[u].sum+=(LL)(tr[u].r-tr[u].l+1)*d;
		tr[u].add+=d;
	}
	else{
		int mid = tr[u].l +tr[u].r>>1;
		pushdown(u);
		if(l<=mid)modify(u<<1,l,r,d);
		if(r>mid)modify(u<<1|1,l,r,d);
		pushup(u);
	}
}

LL query(int u,int l,int r){
	if(tr[u].l>= l and tr[u].r<=r)return tr[u].sum;
	int mid=tr[u].l + tr[u].r >> 1;
	LL sum=0; 
	pushdown(u);
	if(l<=mid)sum=query(u<<1,l,r);
	if(r>mid)sum+=query(u<<1|1,l,r);
	pushup(u);
	
	return sum;
}

int main(){
	char op;
	int l,r,d;
	cin>>n>>m;
	for(int i = 1 ; i <= n ; i ++ )
		cin>>w[i];
	build(1,1,n);
	while(m--){
		cin>>op>>l>>r;
		if(op=='Q'){
			cout<<query(1,l,r)<<endl;
		}
		else{
			cin>>d;
			modify(1,l,r,d);
		}
	}
	return 0;
}

  注意点:1.modify和query中递归都是从l到r,开头的if中的区间都是区间范围在l到r之间;

      2.mid是区间中的mid,tr[u].r+tr[u].r>>1;

      3.注意不要忘记在main函数中建树build,建树过程中初始化节点tr【u】={xxx};

标签:int,modify,LL,tr,build,sum,线段
From: https://www.cnblogs.com/JabberWockY/p/16829883.html

相关文章

  • 李超线段树 学习笔记
    李超线段树学习笔记引入最近一直在做斜率优化的题,然而只会傻傻维护凸包,一到横坐标不单调,就涉及到手打平衡树,但是我实在不想学平衡树了,所以就准备掏出解决处理直线的大宝......
  • 毒瘤线段树
    [SCOI2010]序列操作题目描述lxhgww最近收到了一个\(01\)序列,序列里面包含了\(n\)个数,下标从\(0\)开始。这些数要么是\(0\),要么是\(1\),现在对于这个序列有五种......
  • 数据结构:线段树基础详解
    1.简介线段树,顾名思义,就是由线段构成的树,是一个较为优秀的数据结构,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点,通常用于解决区间类的问题,在各大......
  • fzu_noip 1039(盖楼-线段树)
    盖楼时限:1s内存:32M★问题描述:S举办了一场盖楼比赛,有n位选手参赛,将这n位选手编号为1到n。比赛刚开始时第i位选手的房子的初始高度为Ai,每过一天该选手的房子高度增加Bi。S想......
  • BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
    3110:[Zjoi2013]K大数查询TimeLimit: 20Sec  MemoryLimit: 512MBSubmit: 418  Solved: 235[​​Submit​​][​​Status​​][​​Discuss​​]Des......
  • 动态开点线段树
    普通的线段树是满二叉树,大小为\(4n\),在有些题目中无法满足空间限制,此时就需要用动态开点线段树去解决这个问题0x01口胡开始我们是如何表示一个普通线段树的?左儿子:......
  • BZOJ 4373(算术天才⑨与等差数列-线段树+hash)
    Description算术天才⑨非常喜欢和等差数列玩耍。有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序......
  • CF438D(The Child and Sequence-线段树mod x)
    维护一个区间的和,支持单点修改,区间modx考虑a>x,时,amodx<a/2,否则a=x所以暴力维护就行了#include<iostream>#include<cmath>#include<algorithm>#include<cstdio>#inclu......
  • 线段树优化建图 (CF786B、SNOI2017炸弹)
    先来看板子题:CF786B可以发现,如果对着区间内的每一个点都建一条边,然后跑最短路,我们无论是在空间还是时间复杂度上都是过不去的。因此,我们请出老朋友线段树。参考上图。......
  • 线段树
    线段树是一种数据结构,大概长成这个样子:而线段树的每个节点都包含了它的范围以及它里面的数字,每个节点最多有2个子节点,而节点还包含一个附加信息(例如最大值,求和),而现在我们......