zoukankan      html  css  js  c++  java
  • 树状数组(二叉搜索树)

    数据结构好伤啊,今天碰到一个map竟然自己没有看明白,我会找时间好好写一篇map和vector的博客。

    明白他的存放方式。我先给一张网上找的图片(引用自https://images0.cnblogs.com/blog/402333/201303/02130035-8a70c86ecf024c049fa956184de467ab.png)。此图片来源_sunshine

    不过这张图片比较抽象,也可以观察刘汝佳的训练指南P195,不过最好理解的方法还是看百度的解释(出乎意料的简单啊)

    百度:

    令这棵树的结点编号为C1,C2...Cn。令每个结点的值为这棵树的值的总和,那么容易发现:

    C1 = A1

    C2 = A1 + A2

    C3 = A3

    C4 = A1 + A2 + A3 + A4

    C5 = A5

    C6 = A5 + A6

    C7 = A7

    C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8

    ...

    C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16

    我们不难发现当lowbit(i)为几时我们就把a[i]储存前几位的和,这样就会产生对应的add和sum(add是对a[i]进行添加,sum是对a[i](包括a[i])进行求和)

    sum:先拿a[6]来讲由于a[6]已经储存了a[5]所以我们便不需要再加a[5]了,而神奇的是恰巧loebit(6)为2,这样就可以避开a[5]了,如果想理解的更清楚请学习刘汝佳的训练指南。

    add:不仅要修改本身还要修改后面带有a[i]的,同样的lowbit(i)也可以解决这个问题。

    总之一句话,好神奇!

    这里介绍一道入门题方便理解HDU1518,后附AC代码

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 #define N 50050
     6 int n;
     7 int a[N],c[N];
     8 int lowbit( int x ){
     9     return (x&-x);
    10 }
    11 void add(int i,int w){
    12     while(i<=n){
    13         c[i]+=w;
    14         i=i+lowbit(i);
    15     }
    16 }
    17 int sum(int i){
    18     int sum=0;
    19     while(i>0){
    20         sum+=c[i];
    21         i=i-lowbit(i);
    22     }
    23     return sum;
    24 }
    25 int main()
    26 {
    27     int t,w,u,v;
    28     int cas=0;
    29     char st[100];
    30     scanf("%d",&t);
    31     while(t--){
    32         scanf("%d",&n);
    33         for(int i=0;i<=n;i++)
    34             a[i]=c[i]=0;
    35         for(int i=1;i<=n;i++){
    36             scanf("%d",&w);
    37             add(i,w);
    38         }
    39         printf("Case %d:
    ",++cas);
    40         while(scanf("%s",st),strcmp(st,"End")!=0){
    41             scanf("%d%d",&u,&v);
    42             if(strcmp(st,"Query")==0){
    43                 printf("%d
    ",sum(v)-sum(u-1));
    44             }else if(strcmp(st,"Add")==0){
    45                 add(u,v);
    46             }else if(strcmp(st,"Sub")==0){
    47                 add(u,-v);//化减法为负值;
    48             }
    49 
    50 
    51         }
    52     }
    53 }
    View Code
  • 相关阅读:
    Linux三剑客awk命令试题
    Linux综合练习题
    Linux系统用户角色划分
    Linux添加磁盘fdisk命令
    Linux的七种运行级别
    Linux 文件类型
    Linux开机启动程序
    Linux软件安装
    linux运行级别
    Linux /etc目录下的重要配置文件
  • 原文地址:https://www.cnblogs.com/VectorLin/p/5245006.html
Copyright © 2011-2022 走看看