三篇线段树扫描线总结

HDU 1542 Atlantis,裸面积并

<span style="font-size:24px;">#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 200;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct seg
{
	double l, r, h;
	int s;
	seg(){}
	seg(double a, double b, double c, int d) :l(a), r(b), h(c), s(d){}
	bool operator< (const seg& cmp) const
	{
		return h < cmp.h;
	}
}node[maxn<<2];
double sum[maxn << 2], X[maxn << 2];
int cnt[maxn << 2];

int bin(double a,int r)
{
	int l=0, m;
	while (l <= r)
	{
		m = (l + r) >> 1;
		if (X[m] == a) return m;
		else if (X[m] < a) l = m + 1;
		else r = m - 1;
	}
	return -1;
}

void PushUp(int rt, int l, int r)
{
	if (cnt[rt]) sum[rt] = X[r + 1] - X[l];
	else if (l == r) sum[rt] = 0;
	else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void update(int L, int R, int c, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		cnt[rt] += c;
		PushUp(rt, l, r);
		return;
	}
	int m = (l + r) >> 1;
	if (L <= m) update(L, R, c, lson);
	if (R > m) update(L, R, c, rson);
	PushUp(rt, l, r);
}

int main()
{
	int n,cas = 1;
	while (scanf("%d", &n) && n)
	{
		int m = 0;
		for (int i = 0; i < n; i++)
		{
			double a, b, c, d;
			scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
			node[m] = seg(a, c, b, 1);
			X[m++] = a;
			node[m] = seg(a, c, d, -1);
			X[m++] = c;
		}
		int k = 1;
		sort(X, X + m);
		sort(node, node + m);
		for (int i = 1; i < m; i++)
		if (X[i] != X[i - 1])
			X[k++] = X[i];

		memset(cnt, 0, sizeof(cnt));
		memset(sum, 0, sizeof(sum));
		double ans = 0;
		for (int i = 0; i < m - 1; i++)
		{
			int l = bin(node[i].l, k - 1);
			int r = bin(node[i].r, k - 1) - 1;
			if (l <= r)
				update(l, r, node[i].s, 0, k - 1, 1);
			ans += sum[1] * (node[i + 1].h - node[i].h);
		}
		printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, ans);
	}
	return 0;
}</span>



HDU 1828 Picture 裸周长并

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 22222;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

bool lbd[maxn << 2], rbd[maxn << 2];
int num[maxn << 2], len[maxn << 2], cnt[maxn << 2];
struct Seg
{
	int l, r, h, s;
	Seg(){}
	Seg(int a, int b, int c, int d) :l(a), r(b), h(c), s(d){}
	bool operator<(const Seg& cmp) const
	{
		if (h == cmp.h)
			return s>cmp.s;
		return h < cmp.h;
	}
}seg[maxn];

void PushUp(int rt, int l, int r)
{
	if (cnt[rt])
	{
		len[rt] = r - l + 1;
		num[rt] = 2;
		lbd[rt] = rbd[rt] = true;
	}
	else if (l == r)
	{
		len[rt] = num[rt] = lbd[rt] = rbd[rt] = 0;
	}
	else
	{
		len[rt] = len[rt << 1] + len[rt << 1 | 1];
		num[rt] = num[rt << 1] + num[rt << 1 | 1];
		lbd[rt] = lbd[rt << 1];
		rbd[rt] = rbd[rt << 1 | 1];
		if (lbd[rt << 1 | 1] && rbd[rt << 1])
			num[rt] -= 2;
	}
}

void update(int L, int R, int c, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		cnt[rt] += c;
		PushUp(rt, l, r);
		return;
	}
	int  m = (l + r) >> 1;
	if (L <= m) update(L, R, c, lson);
	if (R > m) update(L, R, c, rson);
	PushUp(rt, l, r);
}

int main()
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		int m = 0;
		int L = maxn, R = -maxn;
		for (int i = 0; i < n; i++)
		{
			int a, b, c, d;
			scanf("%d%d%d%d", &a, &b, &c, &d);
			L = min(L, a);
			R = max(R, c);
			seg[m++] = Seg(a, c, b, 1);
			seg[m++] = Seg(a, c, d, -1);
		}
		sort(seg, seg + m);
		int ans = 0, last = 0;
		for (int i = 0; i < m; i++)
		{
			update(seg[i].l, seg[i].r - 1, seg[i].s, L, R - 1, 1);
			ans += num[1] * (seg[i + 1].h - seg[i].h);
			ans += abs(len[1] - last);
			last = len[1];
		}
		printf("%d\n", ans);
	}
	return 0;
}

HDU 1255 多重覆盖的面积求和

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 2222;
double x[maxn << 2], len[maxn << 2], len2[maxn << 2];
int cnt[maxn << 2];
struct Seg
{
	double l, r, h;
	int s;
	Seg(){}
	Seg(double a, double b, double c, int d) :l(a), r(b), h(c), s(d){}
	bool operator<(const Seg& cmp)
	{
		if (h == cmp.h)
			return s<cmp.s;
		return h < cmp.h;
	}
}seg[maxn << 2];

void init()
{
	memset(cnt, 0, sizeof(cnt));
	memset(len, 0, sizeof(len));
	memset(len2, 0, sizeof(len2));
}


void PushUp(int rt, int l, int r)
{
	if (abs(cnt[rt]) >= 2)
	{
		len2[rt] = len[rt] = x[r + 1] - x[l];
	}
	else if (abs(cnt[rt]) == 1)
	{
		len2[rt] = x[r + 1] - x[l];
		len[rt] = len2[rt << 1] + len2[rt << 1 | 1];
	}
	else if (l == r)
	{
		len[rt] = len2[rt] = 0;
	}
	else
	{
		len[rt] = len[rt << 1] + len[rt << 1 | 1];
		len2[rt] = len2[rt << 1] + len2[rt << 1 | 1];
	}
}

void update(int L, int R, int c, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		cnt[rt] += c;
		PushUp(rt, l, r);
		return;
	}
	int m = (l + r) >> 1;
	if (L <= m) update(L, R, c, lson);
	if (R > m) update(L, R, c, rson);
	PushUp(rt, l, r);
}

int bin(double key, int r)
{
	int l = 0, m;
	while (l <= r)
	{
		m = (l + r) >> 1;
		if (key == x[m]) return m;
		else if (key < x[m]) r = m - 1;
		else l = m + 1;
	}
	return -1;
}

int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int n, m = 0;
		scanf("%d", &n);
		for (int i = 0; i < n; i++)
		{
			double a, b, c, d;
			scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
			x[m] = a;
			seg[m++] = Seg(a, c, b, 1);
			x[m] = c;
			seg[m++] = Seg(a, c, d, -1);
		}
		sort(seg, seg + m);
		sort(x, x + m);
		int k = 1;
		for (int i = 1; i < m; i++)
		if (x[i] != x[i - 1])
			x[k++] = x[i];

		double ans = 0.0;
		for (int i = 0; i < m - 1; i++)
		{
			int l = bin(seg[i].l, k - 1);
			int r = bin(seg[i].r, k - 1) - 1;
			if (l <= r)
				update(l, r, seg[i].s, 0, k - 1, 1);
			ans += len[1] * (seg[i + 1].h - seg[i].h);
		}
		printf("%.2lf\n", ans);
		init();
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值