杭电OJ 1199(C++)

#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 5000;

struct date
{
	int l, r;
	int c, b; //c代表颜色,1为白,0为黑,若区间内颜色单一,则b为1
} init[MAX], tree[MAX * 10], res[MAX * 10]; //init存储输入的数,tree存储线段树,res存储更新后的叶子节点

int num[MAX * 2]; //存所有坐标,用于离散化
int lshnum[MAX * 3]; //存离散化后的坐标
int total = 0; //输入的数字总数量

//离散化数据
void Lsh()
{
	int j = 1;
	lshnum[1] = num[1];
	for (int i = 2; i <= total; i++)
	{
		if (num[i] == lshnum[j])
			continue;

		if (lshnum[j] + 1 < num[i])
			lshnum[++j] = lshnum[j - 1] + 1;

		if (lshnum[j] + 1 < num[i])
			lshnum[++j] = num[i] - 1;

		lshnum[++j] = num[i];
	}
	total = j;
}

//建立线段树
void Build(int l, int r, int rt)
{
	tree[rt].l = l;
	tree[rt].r = r;
	tree[rt].c = 0;
	tree[rt].b = 1;
	if (l == r)
		return;

	int m = (l + r) >> 1;
	Build(l, m, rt << 1);
	Build(m + 1, r, rt << 1 | 1);
}

void PushDown(int rt)
{
	tree[rt << 1].c = tree[rt << 1 | 1].c = tree[rt].c;
	tree[rt << 1].b = tree[rt << 1 | 1].b = 1;
}

int Le, Ri, c;
void UpdateRange(int l, int r, int rt)
{
	if (Le <= l && r <= Ri)
	{
		tree[rt].c = c;
		tree[rt].b = 1;
		return;
	}
	if (tree[rt].b && tree[rt].c == c) //若该区间更新后不变,则直接结束
		return;
	if (tree[rt].b)
		PushDown(rt);
	int m = (l + r) >> 1;
	if (Le <= m)
		UpdateRange(l, m, rt << 1);
	if (Ri > m)
		UpdateRange(m + 1, r, rt << 1 | 1);
	tree[rt].b = 0; //若该区间部分更新,则颜色不单一
}

int cnt = 0;
void FindNode(int l, int r, int rt)
{
	if (l == r)
	{
		res[cnt++] = tree[rt];
		return;
	}
	int m = (l + r) >> 1;
	FindNode(l, m, rt << 1);
	FindNode(m + 1, r, rt << 1 | 1);
}

void PushAllDown(int l, int r, int rt)
{
	if (l == r)
		return;
	if (tree[rt].b)
		PushDown(rt);
	int m = (l + r) >> 1;
	PushAllDown(l, m, rt << 1);
	PushAllDown(m + 1, r, rt << 1 | 1);
}

int main()
{
	int N;
	while (cin >> N)
	{
		cnt = 0;
		total = 0;
		for (int i = 0; i < N; i++)
		{
			int l, r;
			char c;
			cin >> l >> r >> c;
			num[++total] = l;
			num[++total] = r;
			init[i].l = l;
			init[i].r = r;
			if (c == 'w')
				init[i].c = 1;
			else
				init[i].c = 0;
		}

		sort(num + 1, num + 1 + total);
		Lsh();
		Build(1, total, 1);

		for (int i = 0; i < N; i++)
		{
			Le = lower_bound(lshnum + 1, lshnum + total + 1, init[i].l) - lshnum;
			Ri = lower_bound(lshnum + 1, lshnum + total + 1, init[i].r) - lshnum;
			c = init[i].c;
			UpdateRange(1, total, 1);
		}

		PushAllDown(1, total, 1);
		FindNode(1, total, 1);

		int len = 0;
		int l, r;
		for (int i = 0; i < cnt; i++)
		{
			if (!res[i].c)
				continue;
			int j = i;

			while (i + 1 < cnt && res[i + 1].c) //查找最长的白色区间
				i++;

			if (i + 1 <= cnt && len < lshnum[res[i].r] - lshnum[res[j].l] + 1)
			{
				len = lshnum[res[i].r] - lshnum[res[j].l] + 1;
				l = lshnum[res[j].l];
				r = lshnum[res[i].r];
			}
		}

		if (len == 0)
			cout << "On, my god" << endl;
		else
			cout << l << " " << r << endl;
	}
	return 0;
}
发布了138 篇原创文章 · 获赞 1 · 访问量 7012

猜你喜欢

转载自blog.csdn.net/Intelligence1028/article/details/104598063