线段树的分析理解(不定期更新)

基础知识点;

所谓线段树,也就是一颗树,不过这棵树数管的是一个线段,而原本的树管的只是不同的点,其实本质上是一个道理。

线段树算法主要由三部分组成,1建树,2更新3查询。

就以其中第一题为例子
#define lson t<<1
#define rson t<<1|1
#define midl (l+r)/2
#define midr (l+r)/2+1
using namespace std;
const int mm=5e4+9;
class node
{
  public:int l,r,beauty;
}rt[mm*4];

/**这一过程主要就是建立树,给树分配其所管理的区域*/
void build(int t,int l,int r)///这就是建树过程
{ rt[t].l=l;rt[t].r=r;
  if(rt[t].l==rt[t].r)scanf("%d",&rt[t].beauty);
  else
  {
    build(lson,l,midl);build(rson,midr,r);
    rt[t].beauty=rt[lson].beauty+rt[rson].beauty;
  }
}

/**对某个区间,或某个点进行更新*/
void update(int t,int id,int num)///这是更新过程
{
  if(rt[t].l==rt[t].r&&rt[t].l==id)rt[t].beauty+=num;
  else
  {
    if(rt[lson].r>=id)update(lson,id,num);
    else update(rson,id,num);
    rt[t].beauty=rt[lson].beauty+rt[rson].beauty;
  }
}

/**询问某个区间,或某个点的具体情况*/
int query(int t,int l,int r)///这是查询过程
{
  if(rt[t].l==l&&rt[t].r==r)
    return rt[t].beauty;
  if(rt[lson].r>=r)return query(lson,l,r);
  else if(rt[rson].l<=l)return query(rson,l,r);
  else return query(lson,l,rt[lson].r)+query(rson,rt[rson].l,r);
}

线段树之单点更新

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=21335#overview

1.简单的单点更新,诸如求某区间的和,或最大值等,而后有单点更新,这是最水的一类,一看便知,不予解释。

2.求逆序数,勉强算一类,这种需要将其离散化, 办法有两个。

(1)用结构体sort,然后给其离散化。

(2)用二分查找标序。

3.序号类型,排队,插队类的。

 

 

 

 

posted @ 2013-04-01 12:23  剑不飞  阅读(211)  评论(0编辑  收藏  举报