线段树主要的优势是在将一个线性的数组转换成一棵树,从而减少大量的重复操作,并且在树中的节点保存一些信息,以便更好的统计!它的各个操作的复杂度都是在logn的,而且我们知道,对于n个节点来说,最多是只有2n-1个树的节点,另外对于一个如果有maxn个节点,那么我们知道最多要用4*maxn个树的节点,这个可以证明

Poj2828 插入队列,在这个过程中,后一个人可能会覆盖前一个人,那么如何用线段树来解呢,我们知道线段树的叶子节点代表的就是当个节点的值,这里,我们把树的节点表示空位的大小,那么在他插入的时候,然后从后面开始插入,那么如果前面出现重复的,那么因为空位数减少了,那么他们也会插在后面,插入的根据是根据空位的大侠来的,这个更新可以这样写

 Void update(int p,int l,int r,int rt)

{

  当前节点的空位数减少1

  如果p此时比他左孩子节点的空位数大,那么在往有孩子插入,此时空位数p-tree[mid].v

  否则,遍历左孩子
}

Hdoj 1754 要求的是一段区间的最大值,这个在更新的时候,要不断更新父子节点,另外在查询的时候,其实对于每一次,最后的来的值总是从叶子节点的来的,只不过利用二分的思想,让他每次都舍弃了一半的选择!

code

Hdoj1698 hook,这题是用了懒惰标记,要求的问题是在一段区间了进行了某一个操作,然后求整个操作后,总共的和是多少

 懒惰的标记是指如果在更新的过程中,父子节点已经被全部覆盖,那么作为他的孩子节点也坐上同样的标记,这个思想是可以用这样,首先判断当前节点有没被完全覆盖,若是,则进行懒惰标记,对于他的所有孩子节点都是如此

code

Hdoj 3577这题的大意就是 火车有k个座位,乘客可以买从ab的车票,给你一些乘客的买票需求,要你求的就是哪些乘客能够买到票 

  这题用的是线段树,我们知道最好的情况是在每一条路线上能够充分的用上,也就是被完全覆盖,那么在判段许可的时候,如果此段已经被覆盖过,那么不行!这里有一个问

题就是,因为有多个座位,所以每个座位都有一条路线,然后按照上述的思想进行处理即可

问题:第一次wa,是因为这里没注意更新的区间应该是[a,b-1],因为我到了b站之后,就从这站下来了,然后下一次是可以从b站出发的 

code

Poj2528 这一题就是一些海报,要求的是最后没有被完全覆盖的海报总数, 那么怎么求呢,一个问题就是如果我们按照从一开始的数据进行处理的话,那么前一张海报可能会被后一张海报完全覆盖,那么最后的结果就无法有效求出,那么我们可以反过来,那就是从最上面的海报开始,那么判断这段区间内是否已经被完全覆盖过,若是,则不用加1,否则加1

 这题先用离散化,将大的数据映射到比较小的数字上面,然后,根据离散后的数据我们可以得出,现在的问题就是,如何求,才能够去掉被完全覆盖的区间,那么这里我们建立一个hash,这个hash存放的值是表示第i个海报,如果查询的当前的节点的记录值,在hash表里没有被记录过,那么说明此区间没有被完全覆盖,

 现在证明这样做的正确性,首先如果前一张海报被后一张覆盖的情况,那么由于更新后的cnt[]的域记录的也是后一张海报的离散化值,那么就不会记录错误

  总结上面的过程,这个题目的总体思路就是输入数据后,离散处理,在针对每一个进行更新,最后查询,代码待更新。。