
【OI】线段树笔记
用法
是什么,干什么用的就不写了,每篇都有...都看烦了...
过程
主要过程就是 建树 -> 更新 -> 查询输出
板子code
#include <cstdio>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
int n,m,a[100001],tree[1000001],lazy[1000001],mid,b,c,d,e,f,a1,i;
void push_up(int p)
{
tree[p]=tree[p*2]+tree[p*2+1];
}
void swa(int p, int l,int r, int k)
{
lazy[p]+=k;
tree[p]=tree[p]+k*(r-l+1);
}
void push_down(int p, int l, int r)
{
mid=(l+r) / 2;
swa(p*2,l,mid,lazy[p]);
swa(p*2+1,mid+1,r,lazy[p]);
lazy[p]=0;
}
void build(int p, int l, int r)
{
lazy[p]=0;
if (l==r) {tree[p]=a[l]; return;}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tree[p]=tree[p*2+1]+tree[p*2];
}
void update(int ll,int rr,int l,int r,int p,int k)
{
if(ll<=l&&r<=rr)
{
tree[p]+=k*(r-l+1);
lazy[p]+=k;
return;
}
push_down(p,l,r);
int mid=(l+r) / 2;
if(ll<=mid) update(ll,rr,l,mid,p*2,k);
if(rr>mid) update(ll,rr,mid+1,r,p*2+1,k);
push_up(p);
}
int query(int xx,int yy,int l,int r,int p)
{
int sum=0;
if(xx<=l&&r<=yy) return tree[p];
int mid=(l+r)>>1;
push_down(p,l,r);
if(xx<=mid) sum+=query(xx,yy,l,mid,p*2);
if(yy>mid) sum+=query(xx,yy,mid+1,r,p*2+1);
return sum;
}
signed main()
{
cin >> n >> m;
for (i=1; i<=n; i++) cin >> a[i];
build(1,1,n);
while (m--)
{
cin >> a1;
if (a1==1)
{
cin >> b >> c >> d;
update(b,c,1,n,1,d);
}
else
{
cin >> e >> f;
cout << query(e,f,1,n,1) << endl;
}
}
}
有点难懂的是懒标记,多看一会儿能理解。