您的位置:首页 > 其它

HDU 1556 Color the ball 很典型的更新区间查找点的题(线段树树状数组两种解法)

2010-09-22 00:37 656 查看
这道题应该说是线段树和树状数组简单的应用吧!都是用到了基本的功能更新区间查找点!

当使用线段树时,不想原来更新点查找区间那么简单,这里需要在结构体内另外添加一个lnc用来记录更新区间时正好覆盖到该区域时的改变值!然而在查找区间过程中当所查找的区间并不是给定的区间时,需要把给定的区间的sum值进行更新改变!并且也把该子区间的调用update进行更新,这样才能维护一个更新区间查找区间的线段树!

用树状数组时需要注意此时read(i)就是读取下表为i的值为read(i)!

注意数组尽量开大点!避免出现wa或是re!

下面是ac代码给大家参考:

线段树做法:

#include<iostream>
using namespace std;
struct node
{
int left,right;
int sum,lnc;
}tree[300000];
int num[100000];
void init(int id,int l,int r)
{
if(l==r)
{
tree[id].sum=num[l];
tree[id].left=tree[id].right=l;
tree[id].lnc=0;
return ;
}
init(id*2,l,(l+r)/2);
init(id*2+1,(l+r)/2+1,r);
tree[id].sum=tree[2*id].sum+tree[id*2+1].sum;
tree[id].lnc=0;
tree[id].left=l;
tree[id].right=r;
}
void update(int id,int l,int r,int val)
{
if(tree[id].left==l&&tree[id].right==r)
{
tree[id].lnc+=val;
return ;
}
tree[id].sum+=val*(r-l+1);
int mid=(tree[id].left+tree[id].right)/2;
if(r<=mid)
update(2*id,l,r,val);
else if(l>=mid+1)
update(2*id+1,l,r,val);
else
{
update(2*id,l,mid,val);
update(2*id+1,mid+1,r,val);
}
}
int read(int id,int l,int r)
{
if(tree[id].left==l&&tree[id].right==r)
{
return tree[id].sum+tree[id].lnc*(r-l+1);
}
tree[id].sum+=tree[id].lnc*(tree[id].right-tree[id].left+1);
int val=tree[id].lnc;
int mid=(tree[id].left+tree[id].right)/2;
update(2*id,tree[id].left,mid,val);
update(2*id+1,mid+1,tree[id].right,val);
tree[id].lnc=0;
if(r<=mid)
return read(2*id,l,r);
else if(l>=mid+1)
return read(2*id+1,l,r);
else
{
return read(2*id,l,mid)+read(2*id+1,mid+1,r);
}
}
int main()
{
int n,i,a,b,temp;
while(scanf("%d",&n)&&n)
{
memset(num,0,sizeof(num));
memset(tree,0,sizeof(tree));
init(1,1,n);
temp=n;

while(temp--)
{
scanf("%d%d",&a,&b);
update(1,a,b,1);
}
for(i=1;i<=n;i++)
{
printf("%d",read(1,i,i));
if(i!=n)
printf(" ");
else
printf("/n");
}
}
return 0;
}
 

树状数组做法:

#include<iostream>
using namespace std;
int tree[100100];
int maxn;
void update(int k,int v)
{
while(k<=maxn)
{
tree[k]+=v;
k+=k&-k;
}
}
int read(int k)//求区间1到k的和值
{
int sum=0;
while(k>0)
{
sum+=tree[k];
k-=k&-k;
}
return sum;
}
int main()
{
int i,a,b,temp;
while(scanf("%d",&maxn)&&maxn)
{
temp=maxn;
memset(tree,0,sizeof(tree));
while(temp--)
{
scanf("%d%d",&a,&b);
update(a,1);
update(b+1,-1);
}
for(i=1;i<=maxn;i++)
{
printf("%d",read(i));
if(i!=maxn)
printf(" ");
else
printf("/n");
}
}
return 0;
}
 

哈哈保持激情加油了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tree