码迷,mamicode.com
首页 > 其他好文 > 详细

NYOJ 116 士兵杀敌(二) (线段树区间求和)

时间:2015-04-30 09:01:59      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:线段树      数据结构   划分树   应用   

题目链接:NYOJ 116 士兵杀敌(二)

       这一个是线段树的入门级水题,本题要求我们给出某个区间的区间和。这个问题和线段树的单点更新还是基本一致的。只要把单点更新中的值覆盖变为值得叠加,这一题便可以轻松解决了。如果不知道线段树的单点更新,请移步:传送门

【代码如下】

#include <stdio.h>
#include <string.h>
#define MAXN 1<<21  //lg100000 约等于 21
typedef struct{
    int left,right;    
    int sum_kill;      //杀人数 
}Soldier;
Soldier node[MAXN];    
int father[MAXN>>1];
void build(int i,int left,int right){
    node[i].left = left;
    node[i].right = right;
    node[i].sum_kill = 0;
    if(left == right){
        father[left] = i;
        return ;
    }
    build(i<<1,left,(left+right)/2);
    build(2*i+1,1+(left+right)/2,right);
    return ;
}
void Updata(int ri){
    if(ri == 1) return ;
    int fa = ri/2;
    //只要将单点问题的这里变成,下边这样就可以了,不明白的可以想想为什么
    node[fa].sum_kill = node[2*fa].sum_kill + node[2*fa+1].sum_kill;
    Updata(fa);
}
int SK;
void Query(int i,int left,int right){
    if(node[i].left == left && node[i].right == right){
        //这里也是一个和单点问题有区别的 地方 ,把原先单点更新问题中的值覆盖,变为了叠加
        SK += node[i].sum_kill;
        return ;
    }
    if(left <= node[2*i].right){
        if( right <= node[2*i].right )
            Query(2*i,left,right);
        else
            Query(2*i,left,node[2*i].right);
    }
    if(right >= node[2*i+1].left){
        if(left >= node[2*i+1].left)
            Query(2*i+1,left,right);
        else
            Query(2*i+1,node[2*i+1].left,right);
    }
    return ;
}

int main(){
    char op[10];
    int a,b,i;
    int N,M,tmp_kill;
    scanf("%d%d",&N,&M);
    build(1,1,N);
    for(i = 1; i <= N; i++){
        scanf("%d",&tmp_kill);
        node[father[i]].sum_kill += tmp_kill;
        Updata(father[i]);
    }
    while(M--){
        getchar();
        scanf("%s",op);
        SK = 0;
        if(!strcmp(op,"QUERY")){
            scanf("%d%d",&a,&b);
            Query(1,a,b);
            printf("%d\n",SK);
        }else if(!strcmp(op,"ADD")){
            scanf("%d%d",&a,&b);
            node[father[a]].sum_kill += b;
            Updata(father[a]);
        }
    }
    return 0;
}
(如有错误,欢迎指正,转载请注明出处)



NYOJ 116 士兵杀敌(二) (线段树区间求和)

标签:线段树      数据结构   划分树   应用   

原文地址:http://blog.csdn.net/luomingjun12315/article/details/45372669

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!