码迷,mamicode.com
首页 > 编程语言 > 详细

树状数组【模板】

时间:2015-05-05 08:53:55      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

Tree[N] = A[N-2^k+1] + … + A[N]
单点更新,区间求值:树状数组代表区间的和。

const int MAXN = 100010;
int N,Tree[MAXN];

int Lowbit(int i)
{
    return i & (-i);
}

void Update(int i,int x)
{
    while(i <= N)
    {
        Tree[i] = Tree[i] + x;
        i += Lowbit(i);
    }
}

int Query(int N)
{
    int sum = 0;
    while(N > 0)
    {
        sum += Tree[N];
        N -= Lowbit(N);
    }
    return sum;
}
//初始化
memset(Tree,0,sizeof(Tree));
scanf("%d",&N);
for(int i = 1; i <= N; ++i)
{
    int x;
    scanf("%d",&x);
    Update(i,x);
}
单点更新,将第i点的值加上v:Update(i,v)
区间求值,求区间(u,v)的和:Query(v) - Query(u-1)

区间更新,单点求值:树状数组代表单个元素的变化

const int MAXN = 100010;  
int N,Tree[MAXN];  

int Lowbit(int i)  
{  
    return i & (-i);  
}  

void Updata(int i,int x)  
{  
    while(i <= N)  
    {  
        Tree[i] = Tree[i] + x;  
        i = i + Lowbit(i);  
    }  
}  

int Query(int n)  
{  
    int sum = 0;  
    while(n > 0)  
    {  
        sum += Tree[n];  
        n = n - Lowbit(n);  
    }  
    return sum;  
}
区间更新,将区间(u,v)的元素增加d:Update(u,d),Update(v+1,-d)
单点求值,查找第i个元素的值:Query(i)  

求逆序数:
数组Tree[i]表示数字i是否在序列中出现过,如果数字i已经存在于序列中,Tree[i] = 1,否则Tree[i] = 0。按序列从左到右将值为a的元素当作下标为a,赋值为1插入树状数组里,这时,比a的数个数就是i - Query(a)。将全部结果累加起来就是逆序数了。

const int MAXN = 100010;
int N,Tree[MAXN];

int Lowbit(int i)
{
    return i & (-i);
}

void Update(int i,int x)
{
    while(i <= N)
    {
        Tree[i] = Tree[i] + x;
        i = i + Lowbit(i);
    }
}

int Query(int n)
{
    int sum = 0;
    while(n > 0)
    {
        sum += Tree[n];
        n = n - Lowbit(n);
    }
    return sum;
}
//求逆序数:
memset(Tree,0,sizeof(Tree));
for(int i = 1; i <= N; ++i)
{
    cin >> a;
    Update(a,1);
    ans += i - Query(a);
}

二维树状数组:

const int MAXN = 1010;  

int Tree[MAXN][MAXN],N;  
bool Mark[MAXN][MAXN];  

int Lowbit(int i)  
{  
    return i & (-i);  
}  

void Update(int x,int y,int num)  
{  
    for(int i = x; i <= MAXN; i += Lowbit(i))  
        for(int j = y; j <= MAXN; j += Lowbit(j))  
            Tree[i][j] += num;  
}  

int Query(int x,int y)  
{  
    int sum = 0;  
    for(int i = x; i > 0; i -= Lowbit(i))  
        for(int j = y; j > 0; j -= Lowbit(j))  
            sum += Tree[i][j];  
    return sum;  
}  
单点更新,将坐标(x,y)上的元素增加d:Update(x,y,d);
区间求值,求左上角(x2,y2)到右下角(x1,y2)的和: Query(x1,y1) - Query(x1,y2-1) - Query(x2-1,y1) + Query(x2-1,y2-1) 

树状数组【模板】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45488041

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!