zoukankan      html  css  js  c++  java
  • HDU 1166 敌兵布阵 线段树的基本应用——动态区间和问题

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

    简单题,1A了,这个好像就是传说中的“点树”。

    设当前结点表示线段[left, right],编号为i,则结点的左孩子表示线段[left, mid], 编号为2*i,右孩子表示线段[mid+1, right], 编号为2*i+1。

      1 #include <stdio.h>
      2 #include <string.h>
      3 
      4 const int MAXN = 50000;
      5 
      6 //线段树的结点,分别表示一条线段的左端点、右端点、增加的人数
      7 struct Tree_Node
      8 {
      9     int left;
     10     int right;
     11     int num;
     12 }tree[4*MAXN];
     13 
     14 //建立线段树,left和right对应线段树结点中的left和right,i表示当前结点的线段树编号
     15 void build(int left, int right, int i)
     16 {
     17     tree[i].left = left;
     18     tree[i].right = right;
     19     tree[i].num = 0;
     20     if(left == right)
     21     {
     22         return;
     23     }
     24     int mid = (left + right) / 2;
     25     build(left, mid, 2*i);
     26     build(mid+1, right, 2*i+1);
     27 }
     28 
     29 //插入到线段树,tar表示增加人数的那个点在数轴上的编号(不是在线段树上的编号)
     30 //num表示增加的人数,step表示当前结点的线段树编号
     31 void insert(int tar, int num, int step)
     32 {
     33     if(tree[step].left <= tar && tree[step].right >= tar)
     34     {
     35         tree[step].num += num;
     36     }
     37     if(tree[step].left == tree[step].right)
     38     {
     39         return;
     40     }
     41     int mid = (tree[step].left + tree[step].right) / 2;
     42     if(tar <= mid)
     43     {
     44         insert(tar, num, step*2);
     45     }
     46     else
     47     {
     48         insert(tar, num, step*2+1);
     49     }
     50 }
     51 
     52 //left和right表示查询的区间,step表示当前结点的线段树编号
     53 int query(int left, int right, int step)
     54 {
     55     if(tree[step].left == left && tree[step].right == right)
     56     {
     57         return tree[step].num;
     58     }
     59     int mid = (tree[step].left + tree[step].right) / 2;
     60     if(right <= mid)
     61     {
     62         return query(left, right, step*2);
     63     }
     64     else if(left > mid)
     65     {
     66         return query(left, right, step*2+1);
     67     }
     68     else
     69     {
     70         return query(left, mid, step*2) + query(mid+1, right, step*2+1);
     71     }
     72 }
     73 
     74 int main()
     75 {
     76     int t, n, x;
     77     scanf("%d", &t);
     78     for(int item = 1; item <= t; item++)
     79     {
     80         scanf("%d", &n);
     81         build(1, n, 1);
     82         for(int i = 1; i <= n; i++)
     83         {
     84             scanf("%d", &x);
     85             insert(i, x, 1);
     86         }
     87         char cmd[20];
     88         int a, b;
     89         printf("Case %d:
    ", item);
     90         while(scanf("%s", cmd) != EOF && cmd[0] != 'E')
     91         {
     92             scanf("%d %d", &a, &b);
     93             if(cmd[0] == 'Q')
     94             {
     95                 printf("%d
    ", query(a, b, 1));
     96             }
     97             else if(cmd[0] == 'A')
     98             {
     99                 insert(a, b, 1);
    100             }
    101             else if(cmd[0] == 'S')
    102             {
    103                 insert(a, -b, 1);
    104             }
    105         }
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    form表单为什么不能提交
    遇到了消息堆积,但是问题不大
    面试题:如何保证消息不丢失?处理重复消息?消息有序性?消息堆积处理?
    Dubbo学习地址
    Dubbo入门到实战2
    Dubbo入门到实战
    Mybatis 的三种执行器
    从源码理解Druid连接池原理
    Getting NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()
    解决问题:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/3394974.html
Copyright © 2011-2022 走看看