线段树是很重要的数据结构,它的扩展性比树状数组强得多。
文章
知乎有一篇文章讲的不错
核心代码
[N<<2],a[N],tag[N<<2];
ll tree(ll x){return x<<1;}
ll ls(ll x){return x<<1|1;}
ll rsvoid push_up(ll p)
{
[p]=tree[ls(p)]+tree[rs(p)];
tree}
void build(ll p,ll pl,ll pr)
{
[p]=0;
tagif(pl==pr)
{
[p]=a[pl];
treereturn;
}
=(pl+pr)>>1;
ll mid(ls(p),pl,mid);
build(rs(p),mid+1,pr);
build(p);
push_up}
void addtag(ll p,ll pl,ll pr,ll d)
{
[p]+=d;
tag[p]+=d*(pr-pl+1);
tree}
void push_down(ll p,ll pl,ll pr)
{
if(tag[p])
{
=(pl+pr)>>1;
ll mid(ls(p),pl,mid,tag[p]);
addtag(rs(p),mid+1,pr,tag[p]);
addtag[p]=0;
tag}
}
void update(ll L,ll R,ll p,ll pl,ll pr,ll d)
{
if(L<=pl&&pr<=R)
{
(p,pl,pr,d);
addtagreturn;
}
(p,pl,pr);
push_down=(pl+pr)>>1;
ll midif(L<=mid)
(L,R,ls(p),pl,mid,d);
updateif(mid<R)
(L,R,rs(p),mid+1,pr,d);
update(p);
push_up}
(ll L,ll R,ll p,ll pl,ll pr)
ll query{
if(pl>=L&&pr<=R)
return tree[p];
(p,pl,pr);
push_down=0;
ll res=(pl+pr)>>1;
ll midif(L<=mid)
+=query(L,R,ls(p),pl,mid);
resif(R>mid)
+=query(L,R,rs(p),mid+1,pr);
resreturn res;
}
例题
洛谷P3372 [模板]线段树1
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
[N<<2],a[N],tag[N<<2];
ll tree(ll x){return x<<1;}
ll ls(ll x){return x<<1|1;}
ll rsvoid push_up(ll p)
{
[p]=tree[ls(p)]+tree[rs(p)];
tree}
void build(ll p,ll pl,ll pr)
{
[p]=0;
tagif(pl==pr)
{
[p]=a[pl];
treereturn;
}
=(pl+pr)>>1;
ll mid(ls(p),pl,mid);
build(rs(p),mid+1,pr);
build(p);
push_up}
void addtag(ll p,ll pl,ll pr,ll d)
{
[p]+=d;
tag[p]+=d*(pr-pl+1);
tree}
void push_down(ll p,ll pl,ll pr)
{
if(tag[p])
{
=(pl+pr)>>1;
ll mid(ls(p),pl,mid,tag[p]);
addtag(rs(p),mid+1,pr,tag[p]);
addtag[p]=0;
tag}
}
void update(ll L,ll R,ll p,ll pl,ll pr,ll d)
{
if(L<=pl&&pr<=R)
{
(p,pl,pr,d);
addtagreturn;
}
(p,pl,pr);
push_down=(pl+pr)>>1;
ll midif(L<=mid)
(L,R,ls(p),pl,mid,d);
updateif(mid<R)
(L,R,rs(p),mid+1,pr,d);
update(p);
push_up}
(ll L,ll R,ll p,ll pl,ll pr)
ll query{
if(pl>=L&&pr<=R)
return tree[p];
(p,pl,pr);
push_down=0;
ll res=(pl+pr)>>1;
ll midif(L<=mid)
+=query(L,R,ls(p),pl,mid);
resif(R>mid)
+=query(L,R,rs(p),mid+1,pr);
resreturn res;
}
int main() {
::sync_with_stdio(false);
iosint n,m;
>>n>>m;
cinfor(int i=1;i<=n;i++)
>>a[i];
cin(1,1,n);
buildfor(int i=1;i<=m;i++)
{
int op,x,y;
>>op>>x>>y;
cinif(op==1)
{
int k;
>>k;
cin(x,y,1,1,n,k);
update}
else if(op==2)
<<query(x,y,1,1,n)<<'\n';
cout}
return 0;
}