线段树--按点建树

来源:互联网 发布:apache ant linux 编辑:程序博客网 时间:2024/05/29 14:24

按点build线段树,用于求区间的和或者区间最大值。


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 55555;int sum[maxn*4];void PushUp(int rt){    sum[rt] = sum[rt*2] + sum[rt*2+1];//求区间和    sum[rt] = max(sum[rt*2],sum[rt*2+1]);//求区间最大值}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 p, int add, int l, int r, int rt){    if (l == r)    {        sum[rt] += add;        return;    }    int m = (l + r) / 2;    if (p <= m)        update(p, add, l, m, rt*2);    else        update(p, add, 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];    int m = (l + r) / 2;    int ans = 0;    if (ll <= m)        ans += query(ll, rr, l, m, rt*2);    if (rr > m)        ans += query(ll, rr, m + 1, r, rt*2+1);    return ans;}int main(void){    int t, c;    char d[10];    scanf("%d", &t);    for (c = 1; c <= t; c++)    {        printf("Case %d:\n", c);        int n;        scanf("%d", &n);        build(1, n, 1);        while (scanf("%s", d) != EOF)        {            if (d[0] == 'E') break;            int x, y;            scanf("%d%d", &x, &y);            if (d[0] == 'Q')            {                int ans = query(x, y, 1, n, 1);                printf("%d\n", ans);            }            if (d[0] == 'S') update(x, -y, 1, n, 1);            if (d[0] == 'A') update(x, y, 1, n, 1);        }    }    return 0;}



                                             
0 0
原创粉丝点击