zoukankan      html  css  js  c++  java
  • (线段树)敌兵布阵--hdu--1166 (入门)

    链接:

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

    自己第一次在没有看题解AC出来的线段树,写的可能不是太好,再贴个学长的代码,学习一下

    发现自己的Update部分写了很多废话,直接用a[r]里的值就好了,我还传了那么多的值,真傻!

    代码:

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 using namespace std;
      6 
      7 #define Lson r<<1
      8 #define Rson r<<1|1
      9 
     10 const int N = 1e6+5;
     11 
     12 struct SegmentTree
     13 {
     14     int L, R;
     15     int sum, e;
     16     int Mid()
     17     {
     18         return (R+L)>>1;
     19     }
     20 }a[N<<2];
     21 
     22 void BuildSegTree(int r, int L, int R)
     23 {
     24     a[r].L=L, a[r].R=R;
     25     a[r].e=0;
     26 
     27     if(L==R)
     28     {
     29         scanf("%d", &a[r].sum);
     30         return ;
     31     }
     32 
     33     BuildSegTree(Lson, L, a[r].Mid());
     34     BuildSegTree(Rson, a[r].Mid()+1, R);
     35 
     36     a[r].sum = a[Lson].sum + a[Rson].sum;
     37 }
     38 
     39 void Update(int r, int L, int R, int i, int e)
     40 {
     41     a[r].sum += e;
     42 
     43     if(L==R && L==i)
     44         return ;
     45 
     46     if(i<=a[r].Mid())
     47         Update(Lson, L, a[r].Mid(), i, e);
     48     else if(i>a[r].Mid())
     49         Update(Rson, a[r].Mid()+1, R, i, e);
     50 }
     51 
     52 int Query(int r, int L, int R)
     53 {
     54     if(a[r].L==L && a[r].R==R)
     55         return a[r].sum;
     56 
     57     if(R<=a[r].Mid())
     58        return  Query(Lson, L, R);
     59     else if(L>a[r].Mid())
     60        return Query(Rson, L, R);
     61     else
     62     {
     63         long long Lsum = Query(Lson, L, a[r].Mid());
     64         long long Rsum = Query(Rson, a[r].Mid()+1, R);
     65 
     66         return Lsum + Rsum;
     67     }
     68 }
     69 
     70 int main()
     71 {
     72   int t, k=1;
     73   scanf("%d", &t);
     74   while(t--)
     75   {
     76       int n;
     77       scanf("%d", &n);
     78       BuildSegTree(1, 1, n);
     79 
     80       char s[20];
     81       int L, R, i, e;
     82 
     83       printf("Case %d:
    ", k++);
     84 
     85       while(scanf("%s", s), strcmp(s, "End"))
     86       {
     87           if(strcmp(s, "Query")==0)
     88           {
     89               scanf("%d%d", &L, &R);
     90               printf("%d
    ", Query(1, L, R));
     91           }
     92           else if(strcmp(s, "Add")==0)
     93           {
     94               scanf("%d%d", &i, &e);
     95               Update(1, 1, n, i, e);
     96           }
     97           else
     98           {
     99               scanf("%d%d", &i, &e);
    100               Update(1, 1, n, i, -e);
    101           }
    102       }
    103   }
    104    return 0;
    105 }

    学长的代码:

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 
     5 #define maxn 50005
     6 
     7 struct node
     8 {
     9     int L, R, sum;//左右子树,sum记录区间和
    10     int Mid(){return (L+R)/2;}
    11 }tree[maxn*4];//为了保险起见一般定义是四倍
    12 int val[maxn];//保存每个阵地原来的人数
    13 
    14 void Build(int root, int L, int R)//建树
    15 {
    16     tree[root].L = L, tree[root].R = R;
    17 
    18     if(L == R)
    19     {
    20         tree[root].sum = val[L];
    21         return ;
    22     }
    23 
    24     Build(root<<1, L, tree[root].Mid());//<<1 运算符相当于乘上 2,因为是数往左移一位
    25     Build(root<<1|1, tree[root].Mid()+1, R);//|1, 因为左移后最后一位是0, 所以与1进行|相当于+1
    26 
    27     tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;//区间和等于左右区间的和
    28 }
    29 //k表示需要更新的点,e表示需要更新的值
    30 void Insert(int root, int k, int e)
    31 {
    32     tree[root].sum += e;
    33     if(tree[root].L == tree[root].R)
    34         return ;
    35 
    36     if(k <= tree[root].Mid())
    37         Insert(root<<1, k, e);
    38     else
    39         Insert(root<<1|1, k, e);
    40 }
    41 //查询区间LR的和
    42 int Query(int root, int L, int R)
    43 {
    44     if(tree[root].L == L && tree[root].R == R)
    45         return tree[root].sum;
    46 
    47     //如果在左子树区间
    48     if(R <= tree[root].Mid())
    49         return Query(root<<1, L, R);
    50     else if(L > tree[root].Mid())//如果在右子树区间
    51         return Query(root<<1|1, L, R);
    52     else
    53     {//在左右子树
    54         int Lsum = Query(root<<1, L, tree[root].Mid());
    55         int Rsum = Query(root<<1|1, tree[root].Mid()+1, R);
    56 
    57         return Lsum + Rsum;
    58     }
    59 }
    60 
    61 int main()
    62 {
    63     int T, t=1;
    64 
    65     scanf("%d", &T);
    66 
    67     while(T--)
    68     {
    69         int i, N, x, y;
    70 
    71         scanf("%d", &N);
    72 
    73         for(i=1; i<=N; i++)
    74             scanf("%d", &val[i]);
    75         Build(1, 1, N);
    76 
    77         char s[10];
    78 
    79         printf("Case %d:
    ", t++);
    80 
    81         while(scanf("%s", s), s[0] != 'E')
    82         {
    83             scanf("%d%d", &x, &y);
    84 
    85             if(s[0] == 'A')
    86                 Insert(1, x, y);
    87             else if(s[0] == 'S')
    88                 Insert(1, x, -y);
    89             else
    90             {
    91                 int ans = Query(1, x, y);
    92                 printf("%d
    ", ans);
    93             }
    94         }
    95     }
    96 
    97     return 0;
    98 }
    勿忘初心
  • 相关阅读:
    WebService通过SOAP头进行身份验证
    【笔记】NIOS II spi详解
    【笔记】关于NIOS II PIO的几个问题
    【笔记】NIOS II Interval Timer Core详解
    【原创】基于NIOS II SPI的ads8321驱动
    【笔记】MATLAB一些常用函数
    【原创】解决on_chip_memory过小的问题,解决Unable to reach errno ...的问题
    【原创】基于FPGA的等精度测频方法(学习实验)
    【原创】等效采样状态机控制工程(测试通过,待完善说明书)
    【原创】基于NIOS II的ADS1256 SPI驱动
  • 原文地址:https://www.cnblogs.com/YY56/p/4690386.html
Copyright © 2011-2022 走看看