Description
Holedox is a small animal which can be considered as one point. It lives in a straight pipe whose length is L. Holedox can only move along the pipe. Cakes may appear anywhere in the pipe, from time to time. When Holedox wants to eat cakes, it always goes to the nearest one and eats it. If there are many pieces of cake in different directions Holedox can choose, Holedox will choose one in the direction which is the direction of its last movement. If there are no cakes present, Holedox just stays where it is.
Output
Output the total distance Holedox will move. Holedox don’t need to return to the position 0.
Sample Output
Case 1: 9 Case 2: 4 Case 3: 2
Source
2012 Multi-University Training Contest 1
//多校联合第一场中的一道题。题意:在一个长度为n的管道内有n个点(1-n),每个点都可能突然出现一块蛋糕。并且 有一头奶牛(反正是一种动物)初始站在原点0。
给出m个操作: <1> 0 x:表示在x这个点出现了一块蛋糕(可以叠加,并且奶牛每次只能吃一块)
<2> 1 :表示要求奶牛找到离它最近的一块蛋糕并把它吃掉,如果当前离它最近的有多个点,那么就选择它上一次走的方向前进。
最后要求的是所有操作后奶牛共走了多少步。
//很容易看出是点更新,区间访问问题,只是每次查询离当前点左右最近的点的方式有些技巧而已! 做比赛的时候用的是树状数组+二分写,比赛后看到他人用非常巧妙的方法——优先队列解决了,内存、速率高效。 现将本题三种解决(树状数组+二分, 线段树(其实和前面一样的)、 优先队列)方法附下:
(1)、树状数组+二分: 利用树状数组记录每个点之前(包括自身)的蛋糕之和。对当前点st 分别往左右两边二分找出左边第一个i它的sum[i-1]值小于sum[st]的 和右边第一个sum[i]大于sum[st-1]的就是要求的极左极右了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
(2)、线段树:和(1)一样,tree[]中记录每个点之前所有点的蛋糕总数,线段树本身就是二分查询的思想,所以等同于利用二分查询极左极右值。
#include
#include
#include
#include
#include
#include
#include
#include
#include
(3)、优先队列: 用一个降序优先队列ql 来存储小于等于st 的存在蛋糕的点,,一个升序优先队列 qr 来存储大于st 的存在 蛋糕的点, 那么每次从两个队列(某一个或两个队列都为空时特殊判断)中取队头元素则肯定是离它左边最近和右边最近的点。之后比较即可!
#include
#include
#include
#include
#include
#include
#include
#include
#include
//另外此题还有 平衡树和伸展树 两种做法,不懂!表示数据结构太强悍了,各种树!