• 树线段hdu 1166 敌兵布阵(线段树)


    最近研究树线段,稍微总结一下,以后继续补充:

        

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

        题目大意:   给出初始化的区间值,然后有三种讯问

                            Query a b 讯问区间[a,b]值的总和

                            Add a b 第a个元素的值加b

                            Sub a b 第a个元素的值减b

        解题思绪:  线段树 更新:单点增减 讯问:区间和

                           每次更新在结点存储左右子树值的和,查询时就不须要查到最低,实现区间查询

                           更新时间复杂度O(logN),查询时间复杂度O(logN)

        代码:

        

        每日一道理
    生命不是一篇"文摘",不接受平淡,只收藏精彩。她是一个完整的过程,是一个"连载",无论成功还是失败,她都不会在你背后留有空白;生命也不是一次彩排,走得不好还可以从头再来,她绝不给你第二次机会,走过去就无法回头。
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 100000
    #define MID(a,b) (a+b)>>1
    #define L(a) a<<1
    #define R(a) (a<<1)+1
    typedef struct snode{
        int num,left,right;
    }Node;
    int num[MAX];
    Node Tree[MAX<<1];
    
    void Init()
    {
        memset(Tree,0,sizeof(Tree));
    }
    
    void Build(int t,int l,int r)    //以t为根结点,建立左子树为l,右子树为r的线段树
    {
        int mid;
        Tree[t].left=l,Tree[t].right=r;
        if(Tree[t].left==Tree[t].right)
        {
            Tree[t].num=num[l];
            return ;
        }
        mid=MID(Tree[t].left,Tree[t].right);
        Build(L(t),l,mid);
        Build(R(t),mid+1,r);
        Tree[t].num=Tree[L(t)].num+Tree[R(t)].num;
    }
    
    void Insert(int t,int l,int r,int n)  //向t为根结点,左子树为l,右子树为r的结点加上值n
    {
        int mid;
        if(Tree[t].left==l&&Tree[t].right==r)
        {
            Tree[t].num+=n;
            return ;
        }
        mid=MID(Tree[t].left,Tree[t].right);
        if(r<=mid)
            Insert(L(t),l,r,n);
        else if(l>=mid)
            Insert(R(t),l,r,n);
        else
        {
            Insert(L(t),l,mid,n);
            Insert(R(t),mid+1,r,n);
        }
        Tree[t].num+=n;
    }
    
    int Query(int t,int l,int r)    //查询根结点为t,左子树为l,右子树为r的结点的值
    {
        int mid;
        if(Tree[t].left==l&&Tree[t].right==r)
        {
            return Tree[t].num;
        }
        mid=MID(Tree[t].left,Tree[t].right);
        if(l>mid)        //***
            return Query(R(t),l,r);
        else if(r<=mid)   //***
            return Query(L(t),l,r);
        else
        {
            int a,b;
            a=Query(L(t),l,mid);
            b=Query(R(t),mid+1,r);
            return a+b;
        }
    }
    
    int main()
    {
        char ch[10];
        int t,n,i,i1,a,b;
        scanf("%d",&t);
        for(i1=1;i1<=t;i1++)
        {
            Init();         //初始化
            scanf("%d",&n);
            for(i=1;i<=n;i++)
                scanf("%d",&num[i]);
            Build(1,1,n);   //以1为根结点建立线段树
            printf("Case %d:\n",i1);
            while(scanf("%s",ch)&&strcmp(ch,"End")!=0)
            {
                scanf("%d%d",&a,&b);
                if(strcmp(ch,"Add")==0)     //第a个元素加b
                    Insert(1,a,a,b);
                else if(strcmp(ch,"Sub")==0)  //第a个元素减b
                    Insert(1,a,a,-b);
                else
                    printf("%d\n",Query(1,a,b));  //查询[a,b]区间值的总和
            }
        }
        return 0;
    }

        注:原创文章,转载请注明出处

        


    文章结束给大家分享下程序员的一些笑话语录: Borland说我很有前途,Sun笑了;Sun说我很有钱,IBM笑了;IBM说我很专业,Sybase笑了;Sybase说我数据库很牛,Oracle笑了;Oracle说我是开放的,Linux笑了;Linux说我要打败Unix,微软笑了;微软说我的系统很稳定,我们都笑了。

    --------------------------------- 原创文章 By
    树和线段
    ---------------------------------

  • 相关阅读:
    Atitit.Java exe bat  作为windows系统服务程序运行
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3111305.html
Copyright © 2020-2023  润新知