yuwj  

简单排序查找,但是有技巧可以学

详细见代码

/*
思路:
考虑右边区间
按照左端点排序,在已遍历的区间内部找到右端点最小的位置,加到当前的答案上

exp1:两次相同,交换数据
左右两边找到两个区间端点(执行相同操作)将整个的输入完全交换就是执行另一边的情况 -> for(int _ = 0; _ < 2; _++){//... for(auto x : a) a = -a;} // 
exp2:下标数组,快速处理区间排序(需要使用下标找到数据的,代替方案:pair<int,int> 堆,? X 不可替代,此处无法使用堆,其他自带排序的数据结构?)
exp3:(本题)
特判出现完全相等的情况,map统计 + 遍历判断 直接设置0

*/
#include<bits/stdc++.h>
using namespace std;
 
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)
#define sz(a) int((a).size())
 
struct Seg {
	int l, r;
 
	bool operator< (const Seg &oth) const {
		if (l != oth.l)
			return l < oth.l;
		return r < oth.r;
	};
};
 
void solve() {
	int n;
	cin >> n;
	vector<Seg> seg(n);
	for (int i = 0; i < n; i++)
		cin >> seg[i].l >> seg[i].r;
	
	vector<int> ans(n, 0);
	for (int k = 0; k < 2; k++) {
		vector<int> ord(n);
		iota(ord.begin(), ord.end(), 0);
 
		sort(ord.begin(), ord.end(), [&seg](int i, int j){
			if (seg[i].l != seg[j].l)
				return seg[i].l < seg[j].l;
			return seg[i].r > seg[j].r;
		});
 
		set<int> bounds;
		for (int i : ord) {
			auto it = bounds.lower_bound(seg[i].r);
			if (it != bounds.end())
				ans[i] += *it - seg[i].r;
			bounds.insert(seg[i].r);
		}
 
		for (auto &s : seg) {
			s.l = -s.l;
			s.r = -s.r;
			swap(s.l, s.r);
		}
	}
 
	map<Seg, int> cnt;
	for (auto s: seg)
		cnt[s]++;
	for (int i = 0; i < n; i++)
		if (cnt[seg[i]] > 1)
			ans[i] = 0;
	
	for (int a : ans)
		cout << a << '\n';
}
 
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	int t; cin >> t;
	while (t--)
		solve();
	return 0;
}
posted on 2025-04-15 23:02  xiaowang524  阅读(25)  评论(0)    收藏  举报