嗯,看到草稿箱里面那三篇小可怜之后…希望这篇能不咕…。
(`・ω・´)
一.建树
- 在 单点修改+查询求和 中的建树
void push_up(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void build(int rt,int l,int r)//建树
{
if(l == r)
{
sum[rt] = a[l];
return;
}
int m = (l+r)>>1;
build(rt << 1,l,m);//左子树
build(rt <<1|1,m+1,r);//右子树
push_up(rt);
}
2.单点修改+查询区间最大 中的建树
只需改变push_back函数内容,其余不变
void push_up(int rt)
{
sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);//找最大
}
3.区间查询中的建树
只需添加lazy数组初始化
void build(int rt,int l,int r)//建树
{
lazy[rt] = 0;
if(l == r)
{
sum[rt] = a[l];
return;
}
int m = (l+r)>>1;
build(rt << 1,l,m);//左子树
build(rt <<1|1,m+1,r);//右子树
push_up(rt);
}
二.修改(加减)
- 单点修改
void update(int rt,int l,int r,int p,int v,bool judge)//点修改
{
if(l == r)
{
if(judge)
sum[rt] += v;
else
sum[rt] -= v;
return;
}
int m = (l+r) >> 1;
if(p <= m)
update(rt << 1,l,m,p,v,judge);
else
update(rt << 1|1,m+1,r,p,v,judge);
push_up(rt);
}
2.区间修改
void push_down(int rt,int l,int r)
{
if(lazy[rt])
{
int m = (l+r) >> 1;
lazy[rt << 1] += lazy[rt];
lazy[rt << 1|1] += lazy[rt];
sum[rt << 1] += lazy[rt]*(m-l+1);
sum[rt << 1|1] += lazy[rt]*(r-m);
lazy[rt] = 0;
}
}
void update(int rt,int l,int r,int ll,int rr,int v)//区间加
{
if(ll <= l&&r <= rr)
{
lazy[rt] += v;
sum[rt] += v*(r-l+1);
return;
}
push_down(rt,l,r);
int m = (l+r) >> 1;
if(ll <= m)
{
update(rt << 1,l,m,ll,rr,v);
}
if(rr > m)
{
update(rt << 1|1,m+1,r,ll,rr,v);
}
push_up(rt);
}
三.替换
- 单点替换
void update(int rt,int l,int r,int p,int v)//点替换
{
if(l == r)
{
sum[rt] = v;
return;
}
int m = (l+r) >> 1;
if(p <= m)
update(rt << 1,l,m,p,v);
else
update(rt << 1|1,m+1,r,p,v);
push_up(rt);
}
2.区间替换
void push_down(int rt,int l,int r)
{
if(lazy[rt])
{
int m = (l+r) >> 1;
lazy[rt << 1] = lazy[rt];
lazy[rt << 1|1] = lazy[rt];
sum[rt << 1] = lazy[rt]*(m-l+1);
sum[rt << 1|1] = lazy[rt]*(r-m);
lazy[rt] = 0;
}
}
void update(int rt,int l,int r,int ll,int rr,int v)//区间替换
{
if(ll <= l&&r <= rr)
{
lazy[rt] = v;
sum[rt] = v*(r-l+1);
return;
}
push_down(rt,l,r);
int m = (l+r) >> 1;
if(ll <= m)
{
update(rt << 1,l,m,ll,rr,v);
}
if(rr > m)
{
update(rt << 1|1,m+1,r,ll,rr,v);
}
push_up(rt);
}
四.查询
- 单点替换/修改 的求和查询
int query(int rt,int l,int r,int ll,int rr)
{
if(ll <= l && r <= rr)
return sum[rt];
int res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
return res;//和
}
2.区间替换 的求和查询
int query(int rt,int l,int r,int ll,int rr)
{
if(l == r)
return sum[rt];
push_down(rt,l,r);
int res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
push_up(rt);
return res;
}
3.区间修改 的求和查询
int query(int rt,int l,int r,int ll,int rr)
{
if(l == r)
return sum[rt];
push_down(rt,l,r);
long long res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
return res;//
}
还没写完,稍后回来(防止咕咕我先发了orz