简单排序查找,但是有技巧可以学
详细见代码
/*
思路:
考虑右边区间
按照左端点排序,在已遍历的区间内部找到右端点最小的位置,加到当前的答案上
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;
}

浙公网安备 33010602011771号