通过参考大神们的文章,准备开始要一个一个把上面的题目做一遍了,有很多都是原来做过的,现在也再次做一遍方便以后查阅

 

HDU 1166 敌兵布阵

单点增减,区间和查询

线段树:

#include <cstdio>
#include <cstring>

using namespace std;
const int N = 50005;
#define ls o<<1
#define rs o<<1|1

int a[N];
char s[10];

struct Tree{
    int l , r , sum;
}tree[N<<2];

void build(int o , int l , int r)
{
    int m = (l + r) >> 1;
    tree[o].l = l , tree[o].r = r;
    if(l == r){
        tree[o].sum = a[l];
        return ;
    }
    build(ls , l , m);
    build(rs , m+1 , r);
    tree[o].sum = tree[ls].sum + tree[rs].sum;
}

void update(int o , int i , int j , int op)
{
    if(tree[o].l == tree[o].r && tree[o].r == i){
        if(op == 1) tree[o].sum += j;
        if(op == 2) tree[o].sum -= j;
        return ;
    }
    int m = (tree[o].l + tree[o].r) >> 1;
    if(m >= i) update(ls , i , j , op);
    if(m+1 <= i) update(rs , i , j , op);
    tree[o].sum = tree[ls].sum + tree[rs].sum;
}

int query(int o , int s , int t)
{
    if(tree[o].l >= s && tree[o].r <= t)
        return tree[o].sum;
    int m = (tree[o].l + tree[o].r) >> 1;
    int ans = 0;
    if(m >= s) ans += query(ls , s , t);
    if(m+1 <= t) ans += query(rs , s , t);
    return ans;
}

int main()
{
   // freopen("a.in" , "r" , stdin);
    int T , cas = 0;
    scanf("%d" , &T);
    while(T--){
        int n , aa , bb;
        scanf("%d" , &n);
        for(int i = 1 ; i<=n ; i++)
            scanf("%d" , &a[i]);
        build(1 , 1 , n);
        printf("Case %d:\n" , ++cas);
        while(scanf("%s" , s))
        {
            if(s[0] == 'E') break;
            scanf("%d%d" , &aa , &bb);
            if(s[0] == 'A') update(1 , aa , bb , 1);
            else if(s[0] == 'S') update(1 , aa , bb , 2);
            else printf("%d\n" , query(1 , aa , bb));
        }
    }
    return 0;
}
View Code

相关文章: