区间树状数组

先放代码,后面放讲解

const long long MAXN=500233;

class TreeLikeArray
{
    public:
    long long c1[MAXN];
    long long c2[MAXN];
    void add(long long array[],int pos,int key)
    {
        while(pos<MAXN)
        {
            array[pos]+=key;
            pos+=pos&(-pos);
        }
    }
    long long getSum(long long array[],int pos)
    {
        long long ret=0;
        while(pos>0)
        {
            ret+=array[pos];
            pos-=pos&(-pos);
        }return ret;
    }
    long long getSum(int pos)
    {
        return pos*getSum(c1,pos)-getSum(c2,pos);
    }
    long long getSum(int pos1,int pos2)
    {
        return getSum(pos2)-getSum(pos1-1);
    }
    void add(int pos,long long target)
    {
        add(c1,pos,target);
        add(c1,pos+1,-target);
        add(c2,pos,target*(pos-1));
        add(c2,pos+1,-target*pos);

    }
    void add(int pos1,int pos2,long long target)
    {
        add(c1,pos1,target);
        add(c1,pos2+1,-target);
        add(c2,pos1,target*(pos1-1));
        add(c2,pos2+1,-target*(pos2));
    }

};
TreeLikeArray TLA;
时间: 2024-08-24 19:56:20

区间树状数组的相关文章

【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)

[POJ 3321] Apple Tree (dfs重标号设区间+树状数组求和) Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21966   Accepted: 6654 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. K

变化的区间树状数组,单点查询

hdu  1556 Color the ball 要想区间改动的话,那么节点就必须往上更新,查询时往上累加.(区间改动.单点查询) #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=100000+5; int C[maxn]; int n; int lowbit(int x) { return (-x)&x; } void upd

hdu-3333 Turing Tree 离线区间+树状数组(区间不同数的和)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 题目大意: 给出一数组,以及m个查询区间,每次查询该区间不同数字的和.相同数字只加一次. 解题思路: 离线区间,按照区间右端点进行排序. 这样可以从左到右扫一遍,用尺取法一个一个将数字放入树状数组中. 如果这个数字已经在树状数组里面,记录之前的下标,再从树状数组中删去之前下标的这个数字,在当前下标添加该数字.这样可以保证每一步操作,都会使得树状数组中没有重复元素.这样可以直接用树状数组求不同

poj_3321 线段树/树状数组

题目大意 一个果树(每个节点的分叉数目不固定)上有N个分叉点(包括最末的叶节点),则有N-1条边,将分叉点进行从1到N编号,每个分叉点上均可以结水果.开始的时候,每个分叉点都有一个水果,之后进行一系列操作,分为两种操作: (1)Q x: 查询分叉点x以及x的子树上的水果的总数: (2)C x: 更改分叉点x上的结果状态,即原来有水果变为没水果,没水果变为有水果     对于给定的每个Q操作,给出结果. 题目分析 典型的区间操作,但不过是单点更新,区间查询.对于区间操作,可以选用线段树或者树状数组

【初识——树状数组】 区间求最值

说树状数组其实是一个索引表,但是是一个特殊的,树状的索引表,它利用了二进制的一些特性. 就区间求和的要求来说: 首先我们用a[]数组来存储原始数据.然后在a[]之上构造c[]数组来作为树状数组. 如图 这个图表示,当i为奇数时,c[i]中保存的都是a[i]本身.然后,c[2]中保存了a[1], a[2],共2个,c[4]中保存的是a[1], a[2], a[3], a[4],c[6]又是保存两个,c[5]和c[6].c[8]保存8个,c[1], c[2], c[3], c[4], c[5], c

树状数组求区间最大值

------  一直用 线段树 求区间最大值,想换种思路,用树状数组试试,肯定是可以的. 首先要对 树状数组的每个 i 所管理的区间有一定的理解.详见上篇博客: 树状数组(BIT)

hdu 4970 树状数组区间更新 思维题

http://acm.hdu.edu.cn/showproblem.php?pid=4970 好像还没有用树状数组写过区间更新,但是树状数组的确比线段树快很多,不知道跟ZKW线段树比效率怎么样: 先贴个模板: #include <cstdio> const int MAXN = 1024; int B[MAXN], C[MAXN]; #define LOWBIT(x) ((x)&(-(x))) void bit_update(int *a, int p, int d) { for (

【树状数组区间修改单点查询】HDU 4031 Attack

http://acm.hdu.edu.cn/showproblem.php?pid=4031 [题意] 有一个长为n的长城,进行q次操作,d为防护罩的冷却时间,Attack表示区间a-b的墙将在1秒后受到攻击, 询问表示计算第a块墙受到攻击的次数,被防护罩抵消的不算 [思路] 总的攻击次数-防护罩抵消的次数 总的攻击次数可以树状数组维护 防护罩抵消的模拟 [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long l

51nod_1199 树的先跟遍历+区间更新树状数组

题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359185.html 放代码如下: 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeL