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

这道题应该说是线段树和树状数组简单的应用吧!都是用到了基本的功能更新区间查找点!

当使用线段树时,不想原来更新点查找区间那么简单,这里需要在结构体内另外添加一个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)