线段树--按区间建树

来源:互联网 发布:360解压缩软件怎么样 编辑:程序博客网 时间:2024/05/18 17:05

按区间build树,就是为了说明一下向下更新。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100010;int sum[maxn*4];int add[maxn*4];void PushUp(int rt){    sum[rt] = sum[rt*2] + sum[rt*2+1];}void PushDown(int l,int r,int rt){    if(add[rt])    {        int m = (l+r)/2;        add[rt*2] += add[rt];        add[rt*2+1] += add[rt];        sum[rt*2] += (m-l+1)*add[rt];        sum[rt*2+1] += (r-m)*add[rt];        add[rt] = 0;    }}void build(int l, int r, int rt)//建立线段树{    if (l == r)    {        scanf("%d",&sum[rt]);        return;    }    int m = (l + r) / 2;    build(l, m, rt*2);    build(m + 1, r, rt*2+1);    PushUp(rt);}void update(int x,int y,int c, int l, int r, int rt){    if (x<=l && y>=r)    {        sum[rt] += c*(r-l+1);        add[rt] += c;        return;    }    PushDown(l,r,rt);    int m = (l + r) / 2;    if (x <= m)        update(x, y, c, l, m, rt*2);    if(y > m)        update(x, y, c, m + 1, r, rt*2+1);    PushUp(rt);}int query(int ll, int rr, int l, int r, int rt)//查询线段树{    if (ll <= l && rr >= r) return sum[rt];    PushDown(l,r,rt);    int m = (l + r) / 2;    int ret = 0;    if (ll <= m)        ret += query(ll, rr, l, m, rt*2);    if (rr > m)        ret += query(ll, rr, m + 1, r, rt*2+1);    return ret;}int main(){    int n,m,i,j;    char d[10];    while(scanf("%d%d",&n,&m)==2)    {        memset(add,0,sizeof(add));        memset(sum,0,sizeof(sum));        build(1, n, 1);        for(i=0;i<m;i++)        {            scanf("%s",d);            int x, y,z;            if (d[0] == 'Q')            {                scanf("%d%d", &x, &y);                int ans = query(x, y, 1, n, 1);                printf("%d\n", ans);            }            if (d[0] == 'C')            {                scanf("%d%d%d",&x,&y,&z);                update(x, y, z, 1, n, 1);            }        }    }    return 0;}


0 0
原创粉丝点击