hdu_1166 敌兵布阵(树状数组)

来源:互联网 发布:双肩电脑包 知乎 编辑:程序博客网 时间:2024/05/21 16:57

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

分析:

       今天看了树状数组,发现树状数组解这道题,方便很多呀↖(^ω^)↗,

        刘汝佳的《算法竞赛入门经典——训练指南》的194页,树状数组就讲的很好。 实在是不懂就记住普通数组转换成树状数组的公式得了,还是要清楚树状数组的存储结构。

C[i]为树状数组,A[i]为普通数组。


树状数组基础请戳这。。

树状数组基础戳这(霸气英文版)



我的代码:

#include<stdio.h>#include<stdlib.h>#define MANX 50000+10int A[MANX];int C[MANX];int n;int lowbit(int x){    return x&(-x);}int C_sum(int x) //求数组下标中[1,x]的和。{    int sum=0;    while(x>0)    {        sum+=C[x];        x-=lowbit(x);    }    return sum;}void C_Modify(int index,int M) //在数组下标为index 的位置更新值。{    while(index<=n) //n为元素个数。    {        C[index]+=M;        index+=lowbit(index);    }}int main(){    int t;    int i,j,cas;    scanf("%d",&t);    for(cas=1;cas<=t;cas++)    {        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%d",A+i);            C[i]=0;     //每次要初始化树状数组,之前没初始就WA了 o(︶︿︶)o.        }        for(i=1;i<=n;i++)  //创建树状数组。        {            j=i-lowbit(i)+1;            for(;j<=i;j++)            {                C[i]+=A[j];            }        }        char str[10];        printf("Case %d:\n",cas);        while(~scanf("%s",str)&&str[0]!='E')        {            int a,b;            scanf("%d%d",&a,&b);            switch(str[0])            {                case 'A':C_Modify(a,b);break;                case 'S':C_Modify(a,-b);break;                case 'Q':                    {                        int sum1,sum2;                        sum2=C_sum(b);                        if(a-1==0) sum1=0;                        else sum1=C_sum(a-1);                        printf("%d\n",sum2-sum1);                        break;                    }            }        }    }    return 0;}

总结:其实树状数组就是一个两个公式呀。更白一点就是由普通数组转换成树状数组的公式。


原创粉丝点击