题解:AT_abc386_d [ABC386D] Diagonal Separation

分析题面,发现题目求的是是否存在一个白点被 (1,1) 和任意一个黑点围成的矩形内。

先将所有黑点按 x 坐标排序。

枚举所有的白点。

找到所有横坐标不比该白点横坐标小的所有黑点的纵坐标的最大值所属点。

  • 如果该点的纵坐标小于该白点的纵坐标:

    (蓝点代表题目中的白点,红点反之)

    此时满足题目要求,枚举下一个红点。

  • 否则:

    输出 No 舍掉。

其余的输出 Yes


以上的维护方法有很多,我的方法是二分、后缀最大值,可以参考一下。

#include <bits/stdc++.h>
// #define int long long
#define pii pair<int, int>
#define FRE(x) freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout)
#define ALL(x) x.begin(), x.end()
using namespace std;

int _test_ = 1;

const int N = 2e5 + 5;

int n, m, tb, tw, mx[N];
pii B[N], W[N]; // 黑白点

void init() {}

void clear() {}

void solve() {
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int l, r;
		char c;
		cin >> l >> r >> c;
		if (c == 'B') B[++tb] = {l, r};
		else W[++tw] = {l, r};
	}
	sort(B + 1, B + tb + 1); // 排序
	for (int i = tb; i >= 1; i--) {
		mx[i] = max(mx[i + 1], B[i].second); // 后缀最大纵坐标
	}
	for (int i = 1; i <= tw; i++) { // 枚举白点
		int t = lower_bound(B + 1, B + tb + 1, W[i]) - B; // 二分第一个不比该点横坐标小的点
		if (mx[t] >= W[i].second) return cout << "No", void(); // 不合法就舍掉
	}
	cout << "Yes";
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
//	cin >> _test_;
	init();
	while (_test_--) {
		clear();
		solve();
	}
	return 0;
}
posted @   Archippus  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示