树状数组 ( 基础篇 )——敌兵布阵 ( HDU 1166 )

来源:互联网 发布:双轨制对碰算法php 编辑:程序博客网 时间:2024/05/16 04:37
  • 题目链接:
    http://acm.hdu.edu.cn/showproblem.php?pid=1166

  • 分析:
    输入一堆数,范围小于50000,要求对其进行修改具体元素,区间求和两种操作。一看就是树状数组。

  • 题解:

先来一发树状数组的基本模板:

int TreeArray[40005],N;int lowbit(int i)//lowB操作!!!{    return i & (-i);//求出2^p次,p为i的二进制数中,从右往左数第一个1的位置(从0开始数)}void Add(int loc, int value)//将loc位置的元素+=value{    while(loc<N)    {        TreeArray[loc] += value;        loc += lowbit(loc);    }}int Sum(int loc)//求前loc项的元素和{    int ans = 0;    while(loc>0)    {        ans += TreeArray[loc];        loc -= lowbit[loc];    }    return ans;}

然后这题就做完了QAQ

  • AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define LEN 50004using namespace std;int lowbit(int k){    return k&(-k);}int e[LEN];void add(int k, int v)  //第K个元素加上v{    while(k<LEN)    {        e[k] += v;        k += lowbit(k);    }}int sum(int k)  //求前k项的和{    int re=0;    while(k>0)    {        re += e[k];        k -= lowbit(k);    }    return re;}char op[5];int n;int main(){    int T,tt=1;    int i,j;    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);        memset(e, 0, sizeof(e));        for( i=1; i<=n; i++)        {            scanf("%d", &j);            add(i, j);        }        printf("Case %d:\n", tt++);        while( scanf("%s", op) && op[0] != 'E')        {            scanf("%d%d", &i, &j);            if(op[0] == 'Q')            {                printf("%d\n", sum(j) - sum(i-1));            }else if(op[0] == 'A')            {                add(i, j);            }            else                add(i, -j);        }    }}
0 0
原创粉丝点击