题解:AT_abc448_c [ABC448C] Except and Min
AndyHolmes · · 题解
思路
第一种做法
直接使用 multiset 进行模拟。
multiset 天生支持插入数字和删除迭代器的操作,时间复杂度都是
每次询问时:
- 读入需要删除的
K 个球的编号。 - 将对应的
A_{B_i} 从multiset中删除。 - 此时
*s.begin()就是当前袋子中的最小值。 - 输出答案后,再将删除的元素重新插入
multiset中。
代码
#include <bits/stdc++.h>
using namespace std;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, q;
cin >> n >> q;
vector<int> a(n);
multiset<int> s;
for (int i = 0; i < n; i++) {
cin >> a[i];
s.insert(a[i]);
}
while (q -- ) {
int k;
cin >> k;
vector<int> b(k);
for (int i = 0; i < k; i++) {
cin >> b[i]; b[i] -- ;
s.erase(s.find(a[b[i]]));
}
cout << *s.begin() << '\n';
for (int i = 0; i < k; i++) s.insert(a[b[i]]);
}
return 0;
}
时间复杂度:
第二种做法
由于题目给定的
因此可以先将
对于每次询问,只需要在排序后的前
判断某个下标是否在 find 进行线性查找。因为
代码:
#include <bits/stdc++.h>
using namespace std;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, q;
cin >> n >> q;
vector<pair<int, int>> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].first;
a[i].second = i + 1;
}
sort(a.begin(), a.end());
while (q -- ) {
int k;
cin >> k;
vector<int> b(k);
for (int i = 0; i < k; i++) cin >> b[i];
for (int i = 0; i < 6; i++) {
if (find(b.begin(), b.end(), a[i].second) == b.end()) {
cout << a[i].first << '\n';
break;
}
}
}
return 0;
}
时间复杂度: