# HDU 4302 Holedox Eating

119 篇文章 0 订阅
19 篇文章 0 订阅

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
inline int max(int x, int y) { return (x>y)? x: y; }
inline int min(int x, int y) { return (x<y)? x: y; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef long long int64;
#define INF (1<<30)
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "

//	开始小动物在0点, 0~L-1的线段, 会出现食物, 小动物想吃东西的时候找最近的地方去吃, 输出距离和
//	0~L-1 线段树, 单点更新, 区间查询, 维护区间两端点最近的食物位置, 跟每一点的食物数

#define MAXN 100002
int a[MAXN<<2], lidx[MAXN<<2], ridx[MAXN<<2];
int n;

void pushup(int e)
{
//a[e] = a[e<<1]+a[e<<1|1];
lidx[e] = lidx[e<<1];
ridx[e] = ridx[e<<1|1];
if(lidx[e]==-1) lidx[e] = lidx[e<<1|1];
if(ridx[e]==-1) ridx[e] = ridx[e<<1];
}
void build(int l, int r,int e)
{
a[e] =0;  lidx[e] = ridx[e] =-1;
if(l==r) return;
else
{
int mid =(l+r)>>1;
build(l, mid, e<<1);
build(mid+1, r, e<<1|1);
pushup(e);
}
}
void add(int p, int v, int l, int r,int e)
{
if(l==r)
{
a[e] += v;
if(a[e]) lidx[e] = ridx[e] = l;
else lidx[e] = ridx[e] = -1;
//bug(p);bug(a[e]);bug(lidx[e]);bug(ridx[e])<<endl;
}
else
{
int mid =(l+r)>>1;
if(p<=mid)
else
pushup(e);
//bug(l);bug(r);bug(a[e]);bug(lidx[e]);bug(ridx[e])<<endl;
}
}
int lquery(int L, int R, int l, int r, int e)
{
if(L<=l  && r<=R)
{
return lidx[e];
}
else
{
int mid=(l+r)>>1;
int ret1 = -1;
if(L<=mid)
ret1 = lquery(L, R, l, mid, e<<1);
int ret2 = -1;
if(mid+1<=R)
ret2 = lquery(L, R, mid+1, r, e<<1|1);
if(ret1!=-1) return ret1;
else  return ret2;
}
}
int rquery(int L, int R, int l, int r, int e)
{
if(L<=l && r<=R)
{
return ridx[e];
}
else
{
int mid = (l+r)>>1;
int ret1= -1;
if(L<=mid)
ret1 = rquery(L, R, l, mid, e<<1);
int ret2 = -1;
if(mid+1<=R)
ret2 = rquery(L, R, mid+1, r, e<<1|1);
if(ret2!=-1) return ret2;
else  return ret1;
}
}

int dir;
int pos;	//动物位置
int move(int from, int to)		//from -> to	更新方向, 更新蛋糕, 返回距离
{
int ret = abs(to-from);
if(from!=to) dir = from>to;
pos=to;
return ret;
}
int solve(int pos)		//	pos, 动物当前位置
{
int left = rquery(0, pos, 0, n, 1);
int right = lquery(pos, n, 0, n, 1);
//bug(left);bug(right)<<endl;

int goleft = -1;	//1往左, 0往右
if(left == -1 && right!=-1)	//只能往右边
goleft = 0;
else if(right == -1 && left!=-1)		//只能往左边
goleft = 1;
else if(left ==-1 && right==-1)	//没蛋糕
goleft = -1;
else	//两边都有蛋糕
{
int toleft = pos-left;
int toright = right-pos;
if(toleft!=toright)
goleft = toleft<toright;
else
goleft = dir;
}

if(goleft == -1) return 0;		//没蛋糕的时候
else if(goleft) return move(pos, left);
else  return move(pos, right);
}

int main()
{
int T = Rint();
FOR(tt, 1, T)
{
int ret = 0;
dir = 0;		//右边
pos = 0;
n = Rint();	int q = Rint();
build(0, n, 1);		//傻逼了忘调用build看半小时.....
REP(q)
{
int op =Rint();
if(op)
{
ret+=solve(pos);
//bug(ret)<<endl;
}
else
{
int x =Rint();				//0 x(0<=x<=L, x is a integer)    0~n 啊 ...不是n-1....原来比赛的时候是这里一直wa...
}
}
printf("Case %d: %d\n", tt, ret);
}
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
09-23
08-27 128
05-19 348
09-22
10-03
09-20
01-20 1203
12-11 895
08-09 895
10-01 710
12-08 210
10-02 525
07-15 504

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。