线段树模板

来源:互联网 发布:电动牙刷 知乎 编辑:程序博客网 时间:2024/05/18 12:35
#include <iostream>#include <cstdlib>#include <cstdio>#define maxn 100005#define mid (l+r)/2using namespace std;int n, m;long long sum[maxn << 2], maxs[maxn << 2], add[maxn<<2];void PushUp(int id){    sum[id] = sum[id << 1] + sum[id << 1 | 1];    maxs[id] = max(maxs[id << 1], maxs[id << 1 | 1]);}void Pusdown(int pr, int pl, int id){    if(add[id])    {        add[id << 1] += add[id];        add[id << 1 | 1] += add[id];        sum[id << 1] += add[id] * pr;        sum[id << 1 | 1] += add[id] * pl;        maxs[id << 1] += add[id];        maxs[id << 1 | 1] += add[id];        add[id] = 0;    }}void Build(int l, int r, int id) //建树{    add[id] = 0;    if(l == r)    {        scanf("%lld", &sum[id]);        maxs[id] = sum[id];        return ;    }    Build(l, mid, id << 1);    Build(mid + 1, r, id << 1 | 1);    PushUp(id);}void Update(int l, int r, int id, int pos, long long c) //点修改{    if(l > pos || r < pos)        return ;    if(l == r && l == id)    {        sum[id] += c;        maxs[id] += c;        return ;    }    Update(l, mid, id << 1, pos, c);    Update(mid + 1, r, id << 1 | 1, pos, c);    PushUp(id);}void UpDate(int l, int r, int pl, int pr, int id, long long c) //区间修改{    if(l > pr || r < pl)        return ;    if(l >= pl && r <= pr)    {        sum[id] += (r - l + 1) * c;        maxs[id] += c;        add[id] += c;        return;    }    Pusdown(mid - l + 1, r - mid,id);    UpDate(l, mid, pl, pr, id << 1, c);    UpDate(mid + 1, r, pl, pr, id << 1 | 1, c);    PushUp(id);}long long Query(int l, int r, int pl, int pr, int id){    if(r < pl || l > pr)        return 0;    if(l >= pl && r <= pr)    {        return sum[id];    }    Pusdown(mid - l + 1, r - mid, id);    long long sums = 0;    sums += Query(l, mid, pl, pr, id << 1);    sums += Query(mid + 1, r, pl, pr, id << 1 | 1);    return sums;}long long QueryMax(int l, int r, int pl, int pr, int id){    if(r < pl || l > pr)        return 0;    if(l >= pl && r <= pr)    {        return maxs[id];    }    Pusdown(mid - l + 1, r - mid, id);    long long ma = 0;    ma = max(Query(l, mid, pl, pr, id << 1), Query(mid + 1, r, pl, pr, id << 1 | 1));    return ma;}int main(){    char c;    int x, y;    long long d;    scanf("%d %d", &n, &m);    Build(1, n, 1);    getchar();    while(m--)    {        scanf("%c", &c);        if(c == 'Q')        {            scanf("%d %d", &x, &y);            cout << Query(1, n, x, y, 1) << endl;        }        else        {            scanf("%d %d %lld", &x, &y, &d);            UpDate(1, n, x, y, 1, d);        }        getchar();    }    return 0;}