音乐播放器
chu_K's blog
 
文章 标签
22 9

Powered by Gridea | Theme: Fog
载入天数...
载入时分秒...
御风飞行中...

【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;
                }
        }
}

有点难懂的是懒标记,多看一会儿能理解。