题意:一个老鼠在一条长度为L的直线上跑,吃蛋糕,老鼠只能沿直线移动。开始时没有蛋糕,老鼠的初始位置是0.

有两个操作,0 x 代表在位置x添加一个蛋糕; 1 代表老鼠想吃蛋糕。老鼠每次都会选择离自己最近的点,如果两边距离相同,老鼠优先选择与自己当前移动方向相同的点。

求最终移动的总距离。

题解:线段树单点修改+查询区间端点。

设当前位置为pos,每次查询区间[0, pos]的最右端和区间[pos, L]的最左端,比较选择哪个更近。

详细题解见代码注释。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath> #define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1 #define LEFT 0
#define RIGHT 1 using std::min;
using std::max;
using std::abs; const int MAXN = ;
const int INF = << ; int tr[MAXN << ]; //标记哪个点有蛋糕
int left[MAXN << ]; //标记区间[l, r]内有蛋糕的最左端点
int right[MAXN << ]; //标记区间[l, r]内有蛋糕的最右端点
int N, S;
int findL, findR; //标记查找到的任意区间[l, r]中有蛋糕的最左端和最右端 void PushUp( int rt )
{
int lc = rt << ;
int rc = rt << | ;
left[rt] = min( left[lc], left[rc] );
right[rt] = max( right[lc], right[rc] );
return;
} void build( int l, int r, int rt ) //建树
{
tr[rt] = ; //每个点初始蛋糕数目为0
left[rt] = INF;
right[rt] = -INF;
if ( l == r ) return;
int m = ( l + r ) >> ;
build( lson );
build( rson );
return;
} void Update( int pos, int v, int l, int r, int rt ) //更新
{
if ( l == pos && r == pos )
{
tr[rt] += v; //更新该点的蛋糕数目
if ( tr[rt] == ) //如果这一点没有蛋糕了
{
left[rt] = INF;
right[rt] = -INF;
}
else //如果这一点有蛋糕
{
left[rt] = l;
right[rt] = l;
}
return;
} int m = ( l + r ) >> ;
if ( pos <= m ) Update( pos, v, lson );
else Update( pos, v, rson );
PushUp( rt );
return;
} void Query( int L, int R, int l, int r, int rt ) //查询
{
if ( L <= l && r <= R )
{
findL = min( left[rt], findL );
findR = max( right[rt], findR );
return;
}
int m = ( l + r ) >> ;
if ( L <= m ) Query( L, R, lson );
if ( R > m ) Query( L, R, rson );
return;
} int main()
{
int T, cas = ;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d%d", &N, &S );
++N; //原题目中pipe长度为L,编号为0-L,实际上是有(L+1)个点,
//之前没注意,RE了一次,在这里我把每个点编号为1-(L+1) int curPos = ; //当前位置
int curDirection = RIGHT; //当前方向
int sum = ; //移动总路程 build( , N, ); //建树 while ( S-- )
{
//printf("**************curPos=%d curDir=%d\n", curPos, curDirection );
int op, pos;
scanf( "%d", &op );
if ( op == )
{
scanf( "%d", &pos );
Update( pos+, , , N, );
}
else
{
bool find = false;
int findpos; if ( curDirection == LEFT ) //如果当前方向向左
{
int LL, RR;
findL = INF;
findR = -INF;
Query( , curPos, , N, ), LL = findR; //向左走,找离当前点最近的右端点
findL = INF;
findR = -INF;
Query( curPos, N, , N, ), RR = findL; //向右走,找离当前点最近的左端点 if ( LL == -INF && RR == INF ) //两边都没有蛋糕
{
find = false;
}
else if ( LL == -INF && RR != INF ) //只有右边有蛋糕
{
find = true;
findpos = RR;
curDirection = RIGHT;
}
else if ( LL != -INF && RR == INF ) //只有左边有蛋糕
{
find = true;
findpos = LL;
curDirection = LEFT;
}
else //两边都有蛋糕
{
find = true;
if ( curPos - LL <= RR - curPos ) //注意等号,两边距离相等时优先选择左边
{
findpos = LL;
curDirection = LEFT;
}
else
{
findpos = RR;
curDirection = RIGHT;
}
} //printf("LEFT: ");
}
else
{
int LL, RR;
findL = INF;
findR = -INF;
Query( curPos, N, , N, ), RR = findL;
findL = INF;
findR = -INF;
Query( , curPos, , N, ), LL = findR; if ( LL == -INF && RR == INF )
{
find = false;
}
else if ( LL == -INF && RR != INF )
{
find = true;
findpos = RR;
curDirection = RIGHT;
}
else if ( LL != -INF && RR == INF )
{
find = true;
findpos = LL;
curDirection = LEFT;
}
else
{
find = true;
if ( curPos - LL < RR - curPos ) //注意没有等号,两边距离相等时优先选择右边
{
findpos = LL;
curDirection = LEFT;
}
else
{
findpos = RR;
curDirection = RIGHT;
}
} //printf("RIGHT: ");
}
//printf( "findL=%d findR=%d\n", findL, findR ); //printf( "findpos = %d\n", findpos );
if ( find )
{
sum += abs( findpos - curPos );
curPos = findpos;
Update( findpos, -, , N, );
}
}
} printf( "Case %d: %d\n", ++cas, sum );
}
return ;
}

HDU 4302 Holedox Eating (线段树模拟)的更多相关文章

  1. HDU 4302 Holedox Eating (STL + 模拟)

    Holedox Eating Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. hdu 4302 Holedox Eating(优先队列/线段树)

    题意:一只蚂蚁位与原点,在x轴正半轴上会不时地出现一些蛋糕,蚂蚁每次想吃蛋糕时选取最近的去吃,如果前后距离相同,则吃眼前的那一块(即方向为蚂蚁的正前),求最后蚂蚁行进距离. 思路:优先队列q存储蚂蚁前 ...

  3. hdu 4302 Holedox Eating

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 #include <cstdio> #include <cstring> #inc ...

  4. HDU 4302 Holedox Eating(multiset)

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 题意: 在一条直线上,会有多条命令,如果是0,那么就会在x位置处出现一个蛋糕,如果是1,某人就会找到最近的 ...

  5. hdu_5818_Joint Stacks(线段树模拟)

    题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...

  6. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  7. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

  8. 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)

    题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树.  开始和队友 ...

  9. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

随机推荐

  1. C++笔记008:C++对C的扩展——命名空间 namespace基础

    原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 第一, 命名空间的意义 命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突. 我认识两位叫“A”的朋友,一 ...

  2. Bash游戏(51Nod - 1046)

    20180603 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N和K,问最后谁能赢得比赛 ...

  3. 本地打jar包到本地的Maven出库

    1.命令行输入 mvn install:install-file -DgroupId=jar包的groupId -DartifactId=jar包的artifactId -Dversion=jar包的 ...

  4. 【转载】 旧版本Microsoft Office正在配置解决方法

    原文:https://blog.csdn.net/sinat_37215184/article/details/81053931 在运行Microsoft Office 2010等旧版本的Office ...

  5. PADS随记

    在PADS,PCB板设计中,怎么一次就把丝印的大小设置好? CTRL+ALT+F  组合键 打开 选择过滤器(Filter) 如下图 去掉其他的勾选,只选择 Labels . 之后在板子上鼠标拖动选上 ...

  6. 【Android】导航栏(加图片icon)和不同页面的实现(viewpager+tablayout)

    先上图,然后说大致步骤,最后再说细节 图片效果:依序点击导航栏左一.左二.中.右二.右一,最后直接滑动页面(不依靠导航栏切换) 大致步骤如下(文末会有完整代码) [1]创建一个类,我这里取名TabBa ...

  7. php7+apache2.4+mysql 环境配置(window环境)

    最近,小主从事PHP开发.特将最近如何搭建php7的过程记录在此!希望有需要,可以借鉴!( 电脑必须win7 sp1以上, .netframework4 ) Windows7安装php7,Win7+p ...

  8. 我和Python的Py交易》》》》》》 命名空间的小弟作用域

    命名空间的小弟作用域 在这要明确一个观点,在Python中万物皆对象,而变量指向的就是对象. 变量可以是 类名,函数名,储存数据的变量…… 对象可以是  类 ,被封装的一段代码(函数),数据…… 命名 ...

  9. Hibernate学习笔记一

    1 框架体系结构 2 hibernate入门 2.1 ORM框架 Hibernate是一个数据持久化层的ORM框架. Object:对象,java对象,此处特指JavaBean Relational: ...

  10. struts2学习笔记四

    一.contextMap中的数据操作 root根:List 元素1 元素2 元素3 元素4 元素5 contextMap:Map key value application Map key value ...