区间修改,区间查询(线段树)
创始人
2024-02-10 19:46:06
0

线段树

线段树-Segment Tree是一种基于分治思想的二叉树数据结构,用于区间信息修改和查询

区间修改和查询

延迟标记

延迟是设计算法和解决问题的重要思路之一,可以减少徒劳的操作,有效降低时间复杂度。
试想我们在线段树上修改区间[l,r]中的每一个元素的值,而且该区间覆盖了节点node代表的区间[node.l, node.r], 我们当然可以逐一更新子树node中的所有元素,但这个逐一更新的操作是不必要的,因为后续的询问指令可能没有用到[l,r]的子区间。即时更新完全是浪费cpu。
修改时,在节点区间被待修改目标区间完全覆盖时立即返回,回溯时向当前节点累计一个延迟标记,标记其子节点尚未更新。
所有暂时没有被修改的节点都推迟到将来必须被修改时再执行修改(后续查询或修改操作递归进入这些节点时)。
延迟标记是线段树中自上而下传递数据的方式。

例题
A Simple Problem with Integers

给定一个长度为 N 的数列 P,以及 W条指令,每条指令可能是以下两种之一:
C l r d,表示把数列中第 l~r个数都加 d。
Q l r,表示询问数列中第 l∼r个数的和。
对于每个询问,输出一个整数表示答案。
输入格式
第一行两个整数 N,W。
第二行 N个整数 P[i]。
接下来 W行表示 W条指令,每条指令的格式如题所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
1≤N,W≤105, |d|≤10000, |P[i]|≤109
输入样例:
11 4
1 2 3 4 5 6 7 8 9 10 11
Q 5 6
Q 2 9
C 2 9 2
Q 4 10
输出样例:
11
44
61

线段树解决方案

每个节点用结构体模拟
节点包含四个分量: 区间和sum , add增量(兼作延迟标记),左右端点
broadcast函数实现了延迟标记的向下广播
本题属于区间修改,区间查询

代码实现
#include 
#include 
#include 
#include 
using namespace std;typedef long long LL;
//simple integer  
//segment tree with postpone markconst int N = 100007;int n, w;
int P[N];struct STree
{int l,r;LL sum , add;
}ST[4 * N];void pushup(int u)
{ST[u].sum = ST[u << 1].sum + ST[u << 1 | 1].sum;}void broadcast(int k)
{STree & root = ST[k], & left = ST[k << 1];STree & right = ST[k << 1 | 1];if(root.add)//postpone mark is valid{left.add += root.add, left.sum += (LL)(left.r - left.l + 1) * root.add;right.add += root.add, right.sum +=(LL)(right.r - right.l + 1) * root.add;root.add = 0;}
}
void build(int k , int l , int r)
{if(l == r){ST[k] = {l,r,P[l]};return;	} ST[k] = {l,r};int mid = (l + r)>> 1;build(k << 1, l, mid);build(k << 1 | 1, mid + 1, r);pushup(k);
}
//change
void modify(int k , int l , int r, int d)
{if(ST[k].l >= l && ST[k].r <= r){//whole region need to be modifiedST[k].sum +=(LL)(ST[k].r - ST[k].l + 1) * d;ST[k].add += d;//MARK}else{broadcast(k);int mid = ST[k].l + ST[k].r >> 1;if(l <= mid) modify(k << 1, l, r, d);if(r > mid) modify(k << 1 | 1, l, r, d);pushup(k);}}
LL ask(int k , int l , int r)
{if(ST[k].l >= l && ST[k].r <= r) return ST[k].sum;broadcast(k);//only spread one layer every time as needint mid = ST[k].l + ST[k].r >> 1;LL val = 0;//return answerif(l <= mid) val += ask(k << 1, l, r);if( r > mid) val += ask(k << 1|1, l, r);return val;
}
int main()
{
//	freopen("TEST.in","r",stdin);
//	freopen("TEST.out","w",stdout);scanf("%d%d",&n, &w);for(int i = 1; i <= n; i ++)scanf("%d",&P[i]);// read inbuild(1, 1, n);//build Segment treeint l, r, d;char op[2];while(w --){scanf("%s%d%d",op, &l,&r);if(67 == op[0]){scanf("%d",&d);modify(1,l,r,d);}else printf("%lld\n",ask(1,l,r));}//	fclose(stdin);
//	fclose(stdout);return 0;
}

相关内容

热门资讯

清朝有很多有名的历史人物,能给... 清朝有很多有名的历史人物,能给大家说几个清朝的历史人物吗?林则徐,张之洞,乾隆皇帝,曾国藩,朱耷,这...
曹丕的“太子四友”指的是谁 曹丕的“太子四友”指的是谁首先说,曹丕这四个,陈群司马懿是顶级的谋士和政治家,吴质有些小聪明,朱铄不...
在这次遇难者中存在了几名幸存者... 在这次遇难者中存在了几名幸存者。这句话是不是逻辑错误这句话的逻辑没有问题,有问题的是用词不当。遇难者...
在中国古代,有许多充满哲学智慧... 在中国古代,有许多充满哲学智慧的成语典故、寓言故事,如...在中国古代,有许多充满哲学智慧的成语典故...
清澈的意思是什么,… 清澈的意思是什么,…清净而明澈清而透明【造句】看着他清澈而又天真的眼眸,我的心久久不能平静……
蚂蚁森林合种爱情树一方退出怎么... 蚂蚁森林合种爱情树一方退出怎么找回来两个人合种的爱情树,我退出来,我怎么再次加入进去继续合作那个树?...
有好看的古代修炼小说推荐吗? 有好看的古代修炼小说推荐吗?古代重生穿越修炼......让我帮你找一下这些古代修炼的小说,找到这些类...
女主重生爱上前世辜负的人 女主重生爱上前世辜负的人重生我是你正妻渣女重生之竹马重生之弃渣重生之夫君可欺重生之换我疼你重生妇归来...
华胥引有广播剧吗 华胥引有广播剧吗现有的华胥引的广播剧是忆语广播剧社出品的,只有十三月和杯(这个是错字,请无视,居然输...
选文韩麦尔先生在说了,我的朋友... 选文韩麦尔先生在说了,我的朋友们我就要离开你们呢了,再见了银头鲑鱼tj75rt6yturdrruv ...
中通快递从北京保定市到广东揭阳... 中通快递从北京保定市到广东揭阳普宁要多久?中通快递从北京保定市到广东揭阳普宁要多久?从北京到广东需要...
关于离婚悲伤的歌曲 关于离婚悲伤的歌曲关于离婚悲伤的歌曲林俊杰《可惜没如果》 张靓颖《我走以后》 金志文《流着泪说分手》...
形容文笔差怎么说啊? 形容文笔差怎么说啊?哥哥姐姐,麻烦问下,我是做文员的,形容文案方面的工作很差应该怎么说啊?粗鄙怎么样...
我想做未婚妈妈,可行吗? 我想做未婚妈妈,可行吗?没关系吧?我同学好多他们妈妈都是30岁以后省得他们,都没事啊,但是如果你自己...
如何在两个excel表格里筛选... 如何在两个excel表格里筛选出重复的名字如何在两个excel表格里筛选出重复的名字1、电脑打开EX...
且试天下 哪些小说是用白绫做武... 且试天下 哪些小说是用白绫做武器的?神雕侠侣吖- -..小龙女一开始就是用白绫的聊斋 辛十四娘嘿嘿~...
自带高冷体质,笑起来温暖又治愈... 自带高冷体质,笑起来温暖又治愈的星座,你了解吗?虽然天生高冷体质,但是笑起来特别的温暖治愈的新作用天...
火星未解之谜 火星未解之谜多列举一些,每个事例最好长一点,谢啦~“火星人脸”, “地表被水冲击河道”,“原始大气和...
我是1991年10月4号生的,... 我是1991年10月4号生的,是什么星座啊有的说是处女座有的说是天平座,糊涂了,到底是什么啊很负责任...
梦见白狐狸,然后当时我骑着自行... 梦见白狐狸,然后当时我骑着自行车,我想躲开它,他很凶的的追赶我,最后它向我扑了过来,然后我就醒乐.你...