zoukankan      html  css  js  c++  java
  • HDU 1166

    题还是那个题:http://www.cnblogs.com/dilthey/p/6827959.html

    不过我们今天换一种线段树实现来做这道题;

    关于zkw线段树的讲解:https://zhuanlan.zhihu.com/p/29876526(而且我还在文章里被@了,超开心的ヾ(≧∇≦*)ヾ)

    可以说是讲解非常的清楚了!

    AC代码(包含了拥有节点更新、区间查询功能的zkw线段树模板):

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAX 131072
     4 int n,m;
     5 int tree[MAX];
     6 void pushup(int rt){tree[rt]=tree[rt<<1]+tree[rt<<1|1];}
     7 void build()
     8 {
     9     for(m=1;m<n;m<<=1);
    10     for(int i=m;i<=2*m-1;i++) tree[i]=0;//初始化叶子结点
    11     for(int i=m+1;i<=m+n;i++) scanf("%d",&tree[i]);//存储单点值到叶子结点
    12     for(int i=m-1;i;i--) pushup(i);
    13 }
    14 void update(int pos,int val)
    15 {
    16     pos+=m;
    17     tree[pos]+=val;//更新叶子结点
    18     for(pos>>=1;pos;pos>>=1) pushup(pos);
    19 }
    20 int query(int l,int r)
    21 {
    22     int ret=0;
    23     for(l=l+m-1,r=r+m+1;l^r^1;l>>=1,r>>=1)
    24     {
    25         if(~l&1) ret+=tree[l^1];
    26         if(r&1) ret+=tree[r^1];
    27     }
    28     return ret;
    29 }
    30 int main()
    31 {
    32     int t;
    33     scanf("%d",&t);
    34     for(int kase=1;kase<=t;kase++)
    35     {
    36         scanf("%d",&n);
    37         build();
    38         printf("Case %d:
    ",kase);
    39         char input[7];
    40         while(1)
    41         {
    42             scanf("%s",input);
    43             if(input[0]=='E') break;
    44             if(input[0]=='Q')
    45             {
    46                 int l,r;
    47                 scanf("%d%d",&l,&r);
    48                 printf("%d
    ",query(l,r));
    49             }
    50             if(input[0]=='A')
    51             {
    52                 int pos,x;
    53                 scanf("%d%d",&pos,&x);
    54                 update(pos,x);
    55             }
    56             if(input[0]=='S')
    57             {
    58                 int pos,x;
    59                 scanf("%d%d",&pos,&x);
    60                 update(pos,-x);
    61             }
    62         }
    63     }
    64 }

    PS. MAX=131072这个也是比较有讲究的,因为n最大是50000,所以对应的我们的m算出来是65536,所以这棵完全二叉树最后一个叶子节点的编号为2 * 65536 - 1 = 131072 - 1.

    PS2.其实不难发现,zkw线段树也是一种用空间换取时间和代码量的做法.

  • 相关阅读:
    MVC<2:路由映射原理2>
    分支限界>0/1背包 小强斋
    分支限界>装载问题 小强斋
    解空间树搜索 及 最优解 小强斋
    算法>NP难度和NP完全的问题 小强斋
    算法>NP难度和NP完全的问题 小强斋
    分支限界>装载问题 小强斋
    分支限界>0/1背包 小强斋
    分支限界>15谜问题 小强斋
    分支限界>15谜问题 小强斋
  • 原文地址:https://www.cnblogs.com/dilthey/p/7636198.html
Copyright © 2011-2022 走看看