zoukankan      html  css  js  c++  java
  • 树状数组模板 Tree Array

    ---恢复内容开始---

    这几天去浙江省选当垫底(Orz我是蒟蒻),然后顺便复习下树状数组

    关于树状数组,其实很好理解,主要就是lowbit()操作的巧妙

    树状数组是一种非常优雅的数据结构.当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一区间元素之和的时候,可以考虑使用树状数组. 
    换句话说,树状数组最基本的应用: 
    对于一个数组,如果有多次操作,每次的操作有两种:1、修改数组中某一元素的值,2、求和,求数组元素a[1]+a[2]+…a[num]的和。 

    ——Km的小天地

    其实树状数组自己写几个代码就很容易理解了,也可以参见这里(Km的小天地)

     1 // Tree-Array 模板 
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 const int MAX=100000;
     5 int a[MAX+10],c[MAX+10],n,s[MAX+10];
     6 int lowbit(int x) {return x&(-x);}
     7 // 修改:修改第x个元素,把第x个元素改为x+delta
     8 // O(logn)
     9 // 支持单点修改,区间更新复杂度O(nlogn)
    10 void modify(int x,int delta) {
    11     while(x<=n) {
    12         c[x]+=delta;
    13         x+=lowbit(x);
    14     }
    15 } 
    16 // 查询:查询[1,x]区间和,若要查询[x,y],则需调用[1,y]-[1,x]
    17 // O(logn) 
    18 int cal(int x) {
    19     int ret=0;
    20     while(x!=0) {
    21         ret+=c[x];
    22         x-=lowbit(x);
    23     }
    24     return ret;
    25 }
    26 
    27 int main() {
    28     scanf("%d",&n);
    29     for (int i=1;i<=n;++i) {
    30         scanf("%d",&a[i]);
    31         sum[i]=sum[i-1]+a[i];
    32         c[i]=sum[i]-sum[i-lowbit(i)];
    33     }
    34     int T;
    35     scanf("%d",&T);
    36     while(T--) {
    37         //在线修改查询
    38         //这里的代码自行填写 
    39     }
    40     return 0;
    41 }
    View Code

    树状数组的应用

    HDU 1166 敌兵布阵

    纯模板题目,很简单。这里要说一点,我的代码在main部分可能缩进会有点乱,因为HDU经常为多组数据,我是先写好TreeArray再进行添加多数据测试。

     1 # include <iostream>
     2 # include <stdio.h>
     3 # include <string.h>
     4 using namespace std;
     5 int a[50010], c[50010], n, sum[50010]={};
     6 int lowbit(int x) {return x&(-x);}
     7 void mdf(int p, int del) {
     8     while(p<=n) {
     9         c[p]+=del;
    10         p+=lowbit(p);
    11     }
    12 }
    13 int ca(int dg) {
    14     int r=0;
    15     while(dg!=0) {
    16         r+=c[dg];
    17         dg-=lowbit(dg);
    18     }
    19     return r;
    20 }
    21 int main() {int T,ft;
    22     scanf("%d", &T);ft=T;
    23     while(T--) {
    24         printf("Case %d:
    ",ft-T);
    25     scanf("%d", &n);
    26     for (int i=1;i<=n;++i) { 
    27         scanf("%d", &a[i]);
    28         sum[i]=sum[i-1]+a[i];
    29         c[i]=sum[i]-sum[i-lowbit(i)];
    30     }
    31     //for (int i=1;i<=n;++i) printf("%d ", c[i]);
    32     while(1) {
    33         char st[10]; int ta,tb;
    34         scanf("%s", st);
    35         //printf("%s %d %d",st,ta,tb);
    36         if (strcmp(st,"End")==0) break;
    37         scanf("%d %d",&ta,&tb);
    38         if (strcmp(st,"Add")==0) {
    39             mdf(ta,tb);
    40         }
    41         else if (strcmp(st,"Sub")==0) {
    42             mdf(ta,-1*tb);
    43         }
    44         else if (strcmp(st,"Query")==0) {
    45             if(ta>tb) {int p=ta;ta=tb;tb=p;}
    46             printf("%d
    ",ca(tb)-ca(ta-1));
    47         }
    48     }}
    49     return 0;
    50 }
    View Code

    好吧我暂时就写到这一题树状数组,果然我还是太弱了ORZ各位神犇们

    ---恢复内容结束---

    这篇文章由TonyFang发布。 所有解释权归TonyFang所有。 Mailto: tony-fang@map-le.net
  • 相关阅读:
    struts2的@Result annotation 如何添加params,并且在页面取值
    spring @Entity @Table
    @Results( 中 params 怎么用
    Java三种技术架构
    python 内存管理
    wxpyhon 鼠标事件例子
    常用wxPython事件描述
    wxpython 拖动界面时进入假死状态(未响应)解决方法
    python 的一些高级编程技巧
    python 访问器@property的使用方法
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/treearray.html
Copyright © 2011-2022 走看看