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


    学习线段树~~~~~~~~~~~~要好好理解

    此题是单点更新的线段树,考虑基本的询问,更新。

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <stack>
    #include <climits>//形如INT_MAX一类的
    #define MAX 50005
    #define INF 0x7FFFFFFF
    #define REP(i,s,t) for(int i=(s);i<=(t);++i)
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mp(a,b) make_pair(a,b)
    # define eps 1e-5
    //#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
    using namespace std;
    struct node
    {
        int left,right,mid,value,cover;  
    } edge[4*MAX];
    
    void build(int l,int r,int num)
    //l,r为当前节点的左右端点,num为当前节点在数组中的下标
    {
        edge[num].left = l;
        edge[num].right = r;
        edge[num].value = 0;
        edge[num].mid = (l+r) >> 1;
        if(l != r) // 如果不是叶子节点
        {
            build(l,edge[num].mid,num * 2); //左子树
            build(edge[num].mid + 1,r,num*2+1); //右子树
        }
    }
    void update(int num,int mid,int v)
    //单点更新 mid为更新点,v为更新值
    {
        if(edge[num].left == mid && edge[num].right == mid)
        {
            edge[num].value += v;
            return ;
        }
        if(edge[num].mid >= mid)
            update(2*num,mid,v);
        else
            update(2*num+1,mid,v);
        edge[num].value = edge[num*2].value + edge[num*2+1].value; // 注意是‘=’不是‘+=’,更新值
    }
    
    int query(int l,int r,int num)
    {
        if(l <= edge[num].left && r >= edge[num].right)
        {
            return edge[num].value;
        }
        if(r <= edge[num].mid)
            return query(l,r,num*2);
        else if(l >= edge[num].mid + 1)
            return query(l,r,num *2+1);
        else
        {
            return query(l,edge[num].mid,num*2) + query(edge[num].mid+1,r,num*2+1);
        }
    }
    /*
    void insert(int l,int r ,int num)
    //l,r为插入段的左右端点,num为当前结点的下标
    {
        if(l <= edge[num].left && r >= edge[num].right)
        //插入段完全大于当前段
        {
            edge[num].cover = 1;
            return ;
        }
        if(r <= edge[num].mid) //插入段被当前段的左子树包含
            insert(l,r,2 * num);
        else if(l >= edge[num].mid + 1)//插入段被当前段的右子树包含
            insert(l,r,2*num+1);
        else
        {
            insert(l,edge[num].mid, 2* num);
            insert(edge[num].mid+1,r,2*num+1);
        }
    }
    */
    int main()
    {
        int t,i,j;
        int casee = 1;
        char str[10];
        cin >> t;
        while(t--)
        {
            printf("Case %d:
    ",casee++);
            int n,a;
            cin >> n;
            build(1,n,1);
            for(i=1; i<=n; i++)
            {
                scanf("%d",&a);
                update(1,i,a);
            }
            while(scanf("%s",str))
            {
                if(str[0] == 'E')
                    break;
                if(str[0] == 'Q')
                {
                    scanf("%d%d",&i,&j);
                    printf("%d
    ",query(i,j,1));
                }
                if(str[0] == 'A')
                {
                    scanf("%d%d",&i,&j);
                    update(1,i,j);
                }
                if(str[0] == 'S')
                {
                    scanf("%d%d",&i,&j);
                    update(1,i,-j);
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    http://www.bugku.com:Bugku——SQL注入1(http://103.238.227.13:10087/)
    [笔记]一道C语言面试题:大整数乘法
    [笔记] Access Control Lists (ACL) 学习笔记汇总
    [笔记]如何将传统的回调函数转换为C#5.0支持的await格式
    6.链接与导航
    9章 下拉菜单
    11章圆角框 本章很重要 经常用到
    原来链接与导航
    7竖直排列的导航菜单
    8.水平导航菜单
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3199079.html
Copyright © 2020-2023  润新知