Skip to content

Commit 5909a9f

Browse files
committed
range_max&&sum
1 parent 6386b1f commit 5909a9f

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
class Solution {
2+
private:
3+
using ll = long long;
4+
const static int maxn = 1e5+7;
5+
//线段树维护区间和 涉及区间修改
6+
ll MAX[maxn<<2];//表示对应的区间max 有时候需要 -- /*fill(MAX,MAX+(maxn<<2), 0);*/
7+
ll lazyMAX[maxn<<2];//懒标记 表示当前区间的子区间还未被标记信息更新 这里是区间值的变动
8+
ll SUM[maxn<<2];//表示对应的区间和 有时候需要 -- /*fill(SUM,SUM+(maxn<<2), 0);*/
9+
ll lazySUM[maxn<<2];//懒标记 表示当前区间的子区间还未被标记信息更新 这里是区间值的变动
10+
int n,m;
11+
int lc[maxn<<2],rc[maxn<<2];//动态开点
12+
int root=1,cnt=1;//root用于传引用,cnt记录开点数目
13+
14+
inline void pushupMAX(int &rt)
15+
{
16+
MAX[rt]= max(MAX[lc[rt]], MAX[rc[rt]]); //父节点与子节点的关系
17+
}
18+
19+
inline void pushdownMAX(int rt,int l,int r)
20+
{
21+
if(lazyMAX[rt])
22+
{
23+
if(!lc[rt]) lc[rt]=++cnt;//动态开点就这里不一样
24+
if(!rc[rt]) rc[rt]=++cnt;
25+
int mid=(l+r)>>1;
26+
lazyMAX[lc[rt]]=lazyMAX[rt];
27+
lazyMAX[rc[rt]]=lazyMAX[rt];
28+
MAX[lc[rt]]=lazyMAX[rt];
29+
MAX[rc[rt]]=lazyMAX[rt];
30+
lazyMAX[rt]=0;
31+
}
32+
}
33+
inline void updateMAX(int &rt,int l,int r,int vl,int vr,ll v)//rt start with root(1), [vl,vr] 区间每个数加v, [l,r] -- 总 search space
34+
{
35+
if(r<vl || l>vr) return ;
36+
if(!rt) rt=++cnt;//动态开点 边访问边开点
37+
if(vl<=l && r<=vr)
38+
{
39+
MAX[rt]=v;
40+
lazyMAX[rt]=v;
41+
return ;
42+
}
43+
int mid=(l+r)>>1;
44+
pushdownMAX(rt,l,r);
45+
updateMAX(lc[rt],l,mid,vl,vr,v);
46+
updateMAX(rc[rt],mid+1,r,vl,vr,v);
47+
pushupMAX(rt);
48+
}
49+
inline ll queryMAX(int rt,int l,int r,int vl,int vr) //rt start with 1, query [vl,vr] 区间, [l,r] -- 总 search space
50+
{
51+
if(!rt) return LLONG_MIN;//这个节点没有开 直接pass
52+
if(r<vl || l>vr) return LLONG_MIN;
53+
if(vl<=l && r<=vr) return MAX[rt];
54+
int mid=(l+r)>>1;
55+
pushdownMAX(rt,l,r);
56+
return max(queryMAX(lc[rt],l,mid,vl,vr),queryMAX(rc[rt],mid+1,r,vl,vr));
57+
}
58+
59+
inline void pushupSUM(int &rt)
60+
{
61+
SUM[rt]=SUM[lc[rt]]+SUM[rc[rt]]; //父节点与子节点的关系
62+
}
63+
inline void pushdownSUM(int rt,int l,int r)
64+
{
65+
if(lazySUM[rt])
66+
{
67+
if(!lc[rt]) lc[rt]=++cnt;//动态开点就这里不一样
68+
if(!rc[rt]) rc[rt]=++cnt;
69+
int mid=(l+r)>>1;
70+
lazySUM[lc[rt]]=lazySUM[rt];
71+
lazySUM[rc[rt]]=lazySUM[rt];
72+
SUM[lc[rt]]=(mid-l+1)*lazySUM[rt];
73+
SUM[rc[rt]]=(r-mid)*lazySUM[rt];
74+
lazySUM[rt]=0;
75+
}
76+
}
77+
inline void updateSUM(int &rt,int l,int r,int vl,int vr,int v)//rt start with root(1), [vl,vr] 区间每个数加v, [l,r] -- 总 search space
78+
{
79+
if(r<vl || l>vr) return ;
80+
if(!rt) rt=++cnt;//动态开点 边访问边开点
81+
if(vl<=l && r<=vr)
82+
{
83+
SUM[rt]=(r-l+1)*v;
84+
lazySUM[rt]=v;
85+
return ;
86+
}
87+
int mid=(l+r)>>1;
88+
pushdownSUM(rt,l,r);
89+
updateSUM(lc[rt],l,mid,vl,vr,v);
90+
updateSUM(rc[rt],mid+1,r,vl,vr,v);
91+
pushupSUM(rt);
92+
}
93+
inline ll querySUM(int rt,int l,int r,int vl,int vr) //rt start with 1, query [vl,vr] 区间, [l,r] -- 总 search space
94+
{
95+
if(!rt) return 0;//这个节点没有开 直接pass
96+
if(r<vl || l>vr) return 0;
97+
if(vl<=l && r<=vr) return SUM[rt];
98+
int mid=(l+r)>>1;
99+
pushdownSUM(rt,l,r);
100+
return querySUM(lc[rt],l,mid,vl,vr)+querySUM(rc[rt],mid+1,r,vl,vr);
101+
}
102+
};

0 commit comments

Comments
 (0)