[Luogu && ATcoder] AT_abc241_d 题解
AT_abc241_d 题解
思路:
用 multiset 以及 upper_bound() 和 lower_bound() 做此题。
做法:
操作 1:用 .insert(x) 插入元素 \(x\);
操作 2:用 upper_bound() 查找,然后向前 \(k\) 个数,同时判断 \(k\) 是否等于 .begin(),若等于,退出循环并且输出 -1,否则输出 \(A\) 中所有 \(\le x\) 的元素中的第 \(k\) 大值。
操作 3:与操作 2 类似,用 lower_bound() 查找,然后向后 \(k\) 个数,同时判断 \(k\) 是否等于 .end(),若等于,退出循环并且输出 -1,否则输出 \(A\) 中所有 \(\ge x\) 的元素中的第 \(k\) 小值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
multiset<ll> a;
ll q,p,x,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>q;
for(ll i=0;i<q;++i){
cin>>p>>x;
if(p==1){
a.insert(x);
}
else
if(p==2){
cin>>k;
multiset<ll>::iterator n=a.upper_bound(x);
while(n!=a.begin() && k){
k--;
n--;
}
if(k) cout<<-1<<endl;
else cout<<*n<<endl;
}
else{
cin>>k;
multiset<ll>::iterator n=a.lower_bound(x);
while(n!=a.end() && k>1){
k--;
++n;
}
if(n==a.end()) cout<<-1<<endl;
else cout<<*n<<endl;
}
}
return 0;
}
警钟撅烂:
\(x\in[1,10^{18}]\),记得开 long long。
有的编译器很 SB,如果把 multiset<ll>::iterator 改成 auto,它会爆 CE,比如我的 Dev-C++,这种情况可以扔到洛谷 IDE 去。
upper_bound() 和 lower_bound() 返回的类型是迭代器,我这个菜鸡把这玩意给忘了,毕竟几乎没怎么用过这玩意,做的时候因为这玩意爆 CE,卡了半天。

浙公网安备 33010602011771号