andre_joy

导航

hdu 1166

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1166

题意:中文……

mark:线段树。第一次写线段树,目的是减小空间复杂度。

代码:

#include <stdio.h>
#define LL(x) ((x) << 1)
#define RR(x) ((x) << 1 | 1)

typedef struct
{
    int le,ri,mi,su;
}tree;

int a[50010];
tree t[150000];

int build(int l, int r, int s)
{
    t[s].le = l;
    t[s].ri = r;
    t[s].mi = (l+r)/2;
    if(l == r) return t[s].su = a[l];  //就是找这个地方的错,,找了半个小时……
    return t[s].su = (build(l, t[s].mi, LL(s)) + build(t[s].mi+1, r, RR(s)));
}

int query(int l, int r, int s)
{
    if(l == t[s].le && r == t[s].ri) return t[s].su;
    if(l > t[s].mi) return query(l, r, RR(s));
    else if(r <= t[s].mi) return query(l, r, LL(s));
    else return query(l, t[s].mi, LL(s)) + query(t[s].mi+1, r, RR(s));
}

void tran(int p, int x, int s)
{
    t[s].su += x;
    if(t[s].le == t[s].ri) return ;
    if(t[s].mi >= p) tran(p, x, LL(s));
    else if(t[s].mi < p) tran(p, x, RR(s));
}

int main()
{
    int c,n,p,q;
    int i,j;
    char b[10];
    scanf("%d", &c);
    for(i = 0; i < c; i++)
    {
        printf("Case %d:\n", i+1);
        scanf("%d", &n);
        for(j = 1; j <= n; j++)
            scanf("%d", a+j);
        build(1, n, 1);
        while(scanf("%s", b))
        {
            if(b[0] == 'E') break;
            scanf("%d%d", &p, &q);
            switch(b[0])
            {
            case 'Q': printf("%d\n", query(p, q, 1));break;
            case 'A': tran(p, q, 1);break;
            case 'S': tran(p, -q, 1);break;
            }
        }
    }
    return 0;
}

posted on 2012-07-13 21:14  andre_joy  阅读(109)  评论(0编辑  收藏  举报