来自cyc的线段树1

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
long long n,m,k,x,y;
long long a[100000];
struct tree
{
    long long l,r,sum,tag;
}t[400000];
long long ls(long long rt){return rt << 1;}
long long rs(long long rt){return rt << 1 | 1;}
void build(long long rt,long long l,long long r)
{
    t[rt].l = l,t[rt].r = r;
    if(l == r)
	{
        t[rt].sum = a[l];
        return;
    }
    long long mid = (l + r) >> 1;
    build(ls(rt),l,mid);
    build(rs(rt),mid+1,r);
    t[rt].sum = t[ls(rt)].sum + t[rs(rt)].sum;
}
void push_down(long long rt)
{
    t[ls(rt)].sum += t[rt].tag * (t[ls(rt)].r - t[ls(rt)].l + 1);
    t[rs(rt)].sum += t[rt].tag * (t[rs(rt)].r - t[rs(rt)].l + 1);
    t[ls(rt)].tag += t[rt].tag;
    t[rs(rt)].tag += t[rt].tag;
    t[rt].tag = 0;
}
void change(long long rt,long long l,long long r,long long x)
{
    if(l <= t[rt].l && r >= t[rt].r)
	{
        t[rt].sum += (t[rt].r - t[rt].l + 1) * x;
        t[rt].tag += x;
        return;
    }
    if(t[rt].tag) push_down(rt);
    if(l <= t[ls(rt)].r)
	{
        change(ls(rt),l,r,x);
    }
    if(r >= t[rs(rt)].l)
	{
        change(rs(rt),l,r,x);
    }
    t[rt].sum = t[ls(rt)].sum + t[rs(rt)].sum;
}

long long check(long long rt,long long l,long long r)
{
    if(l <= t[rt].l && r >= t[rt].r)
	{
        return t[rt].sum;
    }
    if(t[rt].tag) push_down(rt);
    long long res = 0;
    if(l <= t[ls(rt)].r)
	{
        res += check(ls(rt),l,r);
    }
    if(r >= t[rs(rt)].l)
	{
        res += check(rs(rt),l,r);
    }
    return res;
}
int main()
{
    cin >> n >> m;
    for(long long i = 1;i <= n; i++) cin >> a[i];
    build(1,1,n);
    for(long long i = 1;i <= m; i++)
	{
        cin >> k;
        if(k == 1)
		{
            cin >> x >> y >> k;
            change(1,x,y,k);
        }
		else
		{
            cin >> x >> y;
            cout << check(1,x,y) << endl;
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/lizhengde/p/13206552.html