您的位置:首页 > 其它

hdu1556-树状数组 一维 区间更新 单点查询

2017-05-09 21:11 351 查看
这题可以说是树状数组区间更新,单点查询的模板题。

对于树状数组的区间更新,单点查询,其实就是维护一个差分数组。以该题为例:

定义两个数组a[],b[]。a[]数组表示气球涂色次数,初始均为0。设b
= a
- a[n-1](即b[]数组是a[]数组的一个差分数组),因为a[]数组初始均为0,所以b[]数组初始也为0,且b[1]+b[2]+…+b
= a
- a[0] = a


假设这里我们要对区间为[l,r]的气球图n次色,也就是对a[]数组的[l,r]区间都加n。即:a[1]′=a[1],…,a[l−1]′=a[l−1],a[l]′=a[l]+n,…,a[r]′=a[r]+n,a[r+1]′=a[r+1],…那么对于b[1],…,b[l−1],b[l+1],…,b[r],b[r+2],…不会变(区间外部不变导致b[1−l]和b[r+2−n]不变,区间内部增量相同导致b[l+1−r]不变),但是b[l]会+n,b[r+1]会−n。

这就转变成了对b[]数组的单点更新、区间查询。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
int sz[maxn],n;

int lowbit(int x)
{
return x&(-x);
}

int update(int x,int num)
{
while(x<=n)
{
sz[x] += num;
x += lowbit(x);
}
}

int query(int x)
{
int ans = 0;
while(x>0)
{
ans += sz[x];
x -= lowbit(x);
}
return ans;
}

int main()
{
int a,b;
while(~scanf("%d",&n)&&n!=0)
{
memset(sz,0,sizeof(sz));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
update(a,1);
update(b+1,-1);
}
for(int i=1;i<=n;i++) printf("%d%c",query(i),(i==n ? '\n' : ' '));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐