您的位置:首页 > 其它

树状数组【模板】

2015-05-04 22:46 183 查看
Tree
= A[N-2^k+1] + … + 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 += Lowbit(i);
}
}

int Query(int N)
{
int sum = 0;
while(N > 0)
{
sum += Tree
;
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 - 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 - 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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: