【二维线段树】HDU 1823

这道题是道裸的二维线段树,但要注意细节处理,比如说在将double强制转换成int时不要忘记加一个eps,还有就是-1的特殊处理,不要认为初始化成-1就可以直接输出了,于是我就-1.0挂了好多回。

附上AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

class Seg_Y
{
	public:
		int L, R;
		Seg_Y *l, *r;
		double v;
	public:
		Seg_Y(int L, int R): L(L), R(R) {
			v = -1;
			if (L == R) {
				l = r = 0;
				return;
			}
			int mid = (L+R)>>1;
			l = new Seg_Y(L, mid);
			r = new Seg_Y(mid+1, R);
		}
		void pushUp() {
			if (L == R)
				return;
			v = max(l ? l->v : 0, r ? r->v : 0);
		}
		void insert(int y, double verb) {
			if (L == R) {
				v = max(v, verb);
				return;
			}
			int mid = (L+R)>>1;
			if (y <= mid)
				l->insert(y, verb);
			else
				r->insert(y, verb);
			pushUp();
		}
		double query(int x, int y) {
			if (x <= L && y >= R) {
				return v;
			}
			int mid = (L+R)>>1;
			double ret = -1;
			if (x <= mid)
				ret = max(ret, l->query(x, y));
			if (y > mid)
				ret = max(ret, r->query(x, y));
			return ret;
		}
		~Seg_Y() {
			delete l;
			delete r;
		}
};

class Seg_X
{
	public:
		int L, R;
		Seg_X *l, *r;
		Seg_Y *v;
	public:
		Seg_X(int L, int R, int low, int high): L(L), R(R) {
			v = new Seg_Y(low, high);
			if (L == R) {
				l = r = 0;
				return;
			}
			int mid = (L+R)>>1;
			l = new Seg_X(L, mid, low, high);
			r = new Seg_X(mid+1, R, low, high);
		}
		void insert(int x, int y, double verb) {
			v->insert(y, verb);
			if (L == R) {
				return;
			}
			int mid = (L+R)>>1;
			if (x <= mid)
				l->insert(x, y, verb);
			else
				r->insert(x, y, verb);
		}
		double query(int x, int y, int p, int q) {
			if (x <= L && y >= R)
				return v->query(p, q);
			int mid = (L+R)>>1;
			double ret = -1;
			if (x <= mid)
				ret = max(l->query(x, y, p, q), ret);
			if (y > mid)
				ret = max(r->query(x, y, p, q), ret);
			return ret;
		}
		~Seg_X() {
			delete l;
			delete r;
			delete v;
		}
}*head = 0;

int main()
{
	int m;
	while (scanf("%d", &m) && m != 0) {
		char op;
		int x, y;
		double p, q;
		int ll, rr;
		if (!head)
			delete head;
		head = new Seg_X(100, 200, 0, 1000);
		double ans;
		while (m--) {
			getchar();
			scanf("%c", &op);
			if (op == 'I') {
				scanf("%d %lf %lf", &x, &p, &q);
				y = (int)((p+1e-6)*10.0);
				//printf("!%d!\n", y);
				head->insert(x, y, q);
			} else {
				scanf("%d %d %lf %lf", &x, &y, &p, &q);
				if (x > y)
					swap(x, y);
				if (p > q)
					swap(p, q);
				ll = (int)((p+1e-6)*10.0);
				rr = (int)((q+1e-6)*10.0);
				//printf("!%d %d!\n", ll, rr);
				ans = head->query(x, y, ll, rr);
				if (ans == -1)
					printf("-1\n");
				else
					printf("%.1lf\n", ans);
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值