diff --git a/C279991/.tutorial.md b/C279991/.tutorial.md index 680ec02..6092d34 100644 --- a/C279991/.tutorial.md +++ b/C279991/.tutorial.md @@ -63,3 +63,11 @@ multiset搞一下(又忘记clear了) 按成绩排序后用两个堆分别维护每头牛前后花钱最少的`n/2`头牛,逆序扫一遍即可。 > 辣鸡poj不让用`bits/stdc++.h` + +### O - Leaving Auction + +看完题愣了几秒,发现自己做过。去翻记录,竟然是去年10月份的事情了。深感久日无功,停滞不前,一事无成。 + +很多时候勇于面对事情并不能带来成功,但是如果害怕这种事情的发生而不这样做的话,那就甚至算不上失败了。 + +回到这个题,用一个set来存每个人出的最高价格(因为set自带排序,可以便捷的求出剩下的人出的最高价格)。但是此时我们不能直接输出,而是应当找到出价第二高的人的最高出价,并且在购得者的出价序列里找一个刚好大于此价格的价格,语义上应该使用upper_bound,但是在这题的限制里,lower_bound也是可以的。 diff --git a/C279991/O.cpp b/C279991/O.cpp index 7c92ea4..d7e825d 100644 --- a/C279991/O.cpp +++ b/C279991/O.cpp @@ -2,7 +2,44 @@ #define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING #include using namespace std; +const int N = 200005; +int pmax[N], pmin[N], e[N]; +vector P[N]; int main() { + memset(pmin, 0x3f3f3f3f, sizeof(pmin)); + int n, q, k; + scanf("%d", &n); + for (int i = 0, p, x; i < n; i++) + scanf("%d%d", &p, &x), + P[p].push_back(x), + pmax[p] = max(pmax[p], x), + pmin[p] = min(pmin[p], x); + set> s; + for (int i = 1; i <= n; i++) + if (P[i].size()) + s.insert(make_pair(pmax[i], i)); + scanf("%d", &q); + while (q--) + { + scanf("%d", &k); + for (int i = 0; i < k; i++) + scanf("%d", e + i); + for (int i = 0; i < k; i++) + s.erase(make_pair(pmax[e[i]], e[i])); + if (s.empty()) + puts("0 0"); + else if (s.size() == 1) + printf("%d %d\n", s.begin()->second, pmin[s.begin()->second]); + else + { + auto ite = s.rbegin(); + auto p1 = *(ite++), p2 = *(ite++); + printf("%d %d\n", p1.second, *upper_bound(P[p1.second].begin(), P[p1.second].end(), p2.first)); + } + for (int i = 0; i < k; i++) + if (P[e[i]].size()) + s.insert(make_pair(pmax[e[i]], e[i])); + } return 0; -} +} \ No newline at end of file