[CF12D] Ball
Description
有 N 个女士去参加舞会。每个女士有三个值 a[i],b[i],c[i]
。如果一位女士发现有其它女士的这三个值都比自己高的话就会去跳楼,求有多少跳楼的女士。
Solution
按 ai 为第一关键字,bi 为第二关键字(反),ci 为第三关键字排序后,倒序扫描,这样可以约束有序对的出现顺序
现在 ai 一定按顺序的了,我们只需要考虑 bi 和 ci
维护一个有序对集合 (b,c),满足所有的 (bi,ci) 都被这个集合中的有序对覆盖
遇到一个新的 (bi,ci) 的时候,我们只需要判断第一个 b>=bi 的 b 对应的 c 是否也满足 c>=ci 即可
如果不满足,那么表面它会进入这个有序对集合中,往下扫描所有满足 (c<ci) 的部分,删除这些
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
struct item
{
int a, b, c;
bool operator<(const item &rhs) const
{
if (a != rhs.a)
return a < rhs.a;
if (b != rhs.b)
return b > rhs.b;
return c < rhs.c;
}
};
vector<item> a(n + 2);
for (int i = 1; i <= n; i++)
cin >> a[i].a;
for (int i = 1; i <= n; i++)
cin >> a[i].b;
for (int i = 1; i <= n; i++)
cin >> a[i].c;
sort(&a[1], &a[n + 1]);
int ans = 0;
map<int, int> mp;
mp[9e9] = -9e9;
mp[-9e9] = 9e9;
for (int i = n; i >= 1; i--)
{
auto it = mp.upper_bound(a[i].b);
if (it->second > a[i].c)
++ans;
else
{
mp[a[i].b] = max(mp[a[i].b], a[i].c);
for (auto it = --mp.lower_bound(a[i].b); it->second < a[i].c; mp.erase(it--))
;
}
}
cout << ans << endl;
}