区间修改,区间查询(线段树)
创始人
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;
}

相关内容

热门资讯

国鸿氢能回购5.6万股 金额4... 国鸿氢能(09663)发布公告,2025年7月4日,公司回购股份5.6万股,回购金额为45万港元。根...
西安雁塔法院 | 与列车赛跑!... 一名长期玩“失踪”的失信被执行人,刚踏上西安火车站站台,就被守候多时的雁塔法院执行干警精准锁定、迅速...
风范股份高负债下4800万再买...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会!   7月2日,风范股...
第六届全国导游大赛云南省选拔赛... 中新网云南新闻7月4日电 第六届全国导游大赛云南省选拔赛7月3日在昆明火热开赛。此次大赛由云南省文化...
ETF甄选 | 三大指数涨跌不... 2025年7月4日,市场全天震荡走势,三大指数涨跌不一。截至收盘,沪指涨0.32%,深成指跌0.25...
企业家亚布力热议机器人:下半年... “会,下半年的机器人市场会迎来上市潮。”7月4日,在2025年亚布力中国企业家论坛第十一届创新年会现...
广东建工:联合体中标“深汕特别... 每经AI快讯,7月4日,广东建工(002060.SZ)公告称,全资子公司广东源天与广东振森电力设计研...
董明珠15年来首次落榜! 7月2日,《财富》发布了2025年中国最具影响力的商界女性榜单,立讯精密创始人、董事长王来春连续第三...
微软今年累计裁员1.53万人 ...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! 7月4日,据CNBC...
孙宏斌露面“稳军心”后,融创股... 以8亿元回购40亿境内债后,融创债务重组再有进展。 债务重组相对顺利的融创中国(01918.HK),...