Hdu 4302 Holedox Eating

Binary-index-array + binary search and slight simulation. (of course seg-tree would be more effcient)

For the simulation, I will record the current position(cp) and current direction(cd) of Holedox.

and for each query, get the rightmost cake in Holedox left-side(cl) and the leftmost cake in Holedox right-side(cr).

Then according to cl and cr, we do some classification, as to change cp and cd.

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <cctype>
#include <queue>
#include <stack>
using namespace std;
#define MS(c, a) memset(c, a, sizeof c)
#define Rep(c, a, b) for (int c = (a); c < (b); c++)
#define Nre(c, a, b) for (int c = (a); c > (b); c--)
#define MAXN (100010)
typedef long long LL;

struct BIA
{
	int t[MAXN];
	void ini()
	{
		MS(t, 0);
	}
	int low(int x)
	{
		return -x & x;
	}
	void upd(int x, int ad)
	{
		for (; x < MAXN; x += low(x)) t[x] += ad;
	}
	int operator [] (int x)
	{
		int tsu = 0;
		for (; x; x -= low(x)) tsu += t[x];
		return tsu;
	}
} bia;

int LBS(int l, int r)
{
	int ans = -1;
	while (l <= r)
	{
		int m = (l + r) >> 1;
		if (bia[m] - bia[l - 1])
		{
			ans = m;
			r = m - 1;
		}
		else l = m + 1;
	}
	return ans;
}

int RBS(int l, int r)
{
	int ans = -1;
	while (l <= r)
	{
		int m = (l + r) >> 1;
		if (bia[r] - bia[m - 1])
		{
			ans = m;
			l = m + 1;
		}
		else r = m - 1;
	}
	return ans;
}

int l, n;

int main()
{
	int T, cd, cp, op, x, cl, cr;
	LL dis;
	scanf("%d", &T);
	Rep(Cas , 1, T + 1)
	{
		scanf("%d%d", &l, &n);
		l++;
		bia.ini();
		cd = cp = 1;
		dis = 0;
		while (n--)
		{
			scanf("%d", &op);
			if (op)
			{
				cl = RBS(1, cp);
				cr = LBS(cp, l);
				if (cl != -1 || cr != -1) //Classification
				{
					if (cl == -1)
					{
						dis += cr - cp;
						bia.upd(cr, -1);
						cp = cr;
						cd = 1;
					}
					else if (cr == -1)
					{
						dis += cp - cl;
						bia.upd(cl, -1);
						cp = cl;
						cd = 0;
					}
					else if (cl == cr)
						bia.upd(cl, -1);
					else if (cp - cl == cr - cp)
					{
						if (cd)	
						{
							dis += cr - cp;
							bia.upd(cr, -1);
							cp = cr;
						}
						else 
						{
							dis += cp - cl;
							bia.upd(cl, -1);
							cp = cl;
						}
					}
					else if (cp - cl < cr - cp)
					{
						dis += cp - cl;
						bia.upd(cl, -1);
						cp = cl;
						cd = 0;
					}
					else
					{
						dis += cr - cp;
						bia.upd(cr, -1);
						cp = cr;
						cd = 1;
					}
				}
			}
			else
			{
				scanf("%d", &x);
				bia.upd(x + 1, 1);
			}
		}
		printf("Case %d: %lld\n", Cas, dis);
	}
	return 0;
}

The classification of cl and cr is slightly the same as plug-DP  {= A =}.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值