HDU - 1166.敌兵布阵


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166


考查树状数组,线段树也可以做


#include <cstdio>
#include <string.h>
#include <string>
#include <iostream>

#define MAX 50000 + 10

using namespace std;

//int a[MAX];
int c[MAX];

int lowbit( int x ) {   // 区间长度
    return x & -x;
}

int getSum( int k ) { //1~k的区间和
    int sum = 0;
    while( k ) {
        sum += c[k];
        k -= lowbit( k );
    }

    return sum;
}

void add( int k, int num, int n ) {  // 对数组进行改变
    while( k <= n ) {
        c[k] += num;
        k += lowbit( k );
    }
}

int main() {
    int T;
    int t = 1;
    scanf( "%d", &T );

    while( t <= T ) {
        printf( "Case %d:\n", t++ );
        //memset( a, 0, sizeof( a ) );
        memset( c, 0, sizeof( c ) );

        int N, num;
        scanf( "%d", &N );
        for( int i = 1; i <= N; i++ ) {
            scanf( "%d", &num );
            add( i, num, N );
        }

        getchar();
        while( 1 ) {
            string op;
            int x, y;
            cin >> op;
            if( op == "End" ) {
                break;
            }
            scanf( "%d%d", &x, &y );
            getchar();
            if( op == "Add" ) {
                add( x, y, N );
            }
            else if( op == "Sub" ) {
                add( x, -y, N );
            }
            else if( op == "Query" ) {
                printf( "%d\n", getSum( y ) - getSum( x - 1 ) );
            }
        }
    }

    return 0;
}


线段树版本

#include <iostream>
#include <string>
#include <cstring>

#define MAX 50005

using namespace std;

typedef struct {
    int l;
    int r;
    int sum;
} Node;

Node tree[4 * MAX];
int c[MAX];

void build( int root, int l, int r ) {
    tree[root].l = l;
    tree[root].r = r;

    if( tree[root].l == tree[root].r ) {
        tree[root].sum = c[l];
        return;
    }

    int mid = ( l + r ) / 2;
    build( root * 2, l, mid );
    build( root * 2 + 1, mid + 1, r );

    tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}

void update( int root, int pos, int val ) {
    if( tree[root].l == tree[root].r ) {
        tree[root].sum += val;
        return;
    }

    int mid = ( tree[root].l + tree[root].r ) / 2;
    if( pos <= mid ) {
        update( root * 2, pos, val );
    }
    else {
        update( root * 2 + 1, pos, val );
    }

    tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}

int query( int root, int l, int r ) {
    if( l <= tree[root].l && r >= tree[root].r ) {
        return tree[root].sum;
    }
    int mid = ( tree[root].l + tree[root].r ) / 2;
    int ans = 0;

    if( l <= mid ) {
        ans += query( root * 2, l, r );
    }
    if( r > mid ) {
        ans += query( root * 2 + 1, l, r );
    }

    return ans;
}

int main() {
    int T;
    int t = 1;
    scanf( "%d", &T );

    while( t <= T ) {
        printf( "Case %d:\n", t++ );
        //memset( a, 0, sizeof( a ) );
        memset( c, 0, sizeof( c ) );

        int N, num;
        scanf( "%d", &N );
        for( int i = 1; i <= N; i++ ) {
            scanf( "%d", &c[i] );
        }

        build( 1, 1, N );

        getchar();
        while( 1 ) {
            string op;
            int x, y;
            cin >> op;
            if( op == "End" ) {
                break;
            }
            scanf( "%d%d", &x, &y );
            getchar();
            if( op == "Add" ) {
                update( 1, x, y );
            }
            else if( op == "Sub" ) {
                update( 1, x, -y );
            }
            else if( op == "Query" ) {
                printf( "%d\n", query( 1, x, y ) );
            }
        }
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值