题意:
就是给你3中操作,操作1是让x进去,操作2是查询小于x的数中第k大的,操作3是查询大于x的数中第k小的。k<=5。刚开始我还以为是树状数组,看错题目了。其实就是multiset去维护一下就行了,当时卡在怎么求<=x的数了,其实有两种办法,一种是都加上负号,这样就是反过来的了。还有一种就是求出来的auto now是可以直接–和++的,所以判断就行了,不过要注意细节。
代码:
加负号:
int T,n,m,k;
int va[N];
multiset<int > s1,s2;
signed main()
{
IOS;
cin>>n;
while(n--)
{
int op,a,b;
cin>>op;
if(op==1)
{
cin>>a;
s1.insert(a);
s2.insert(-a);
}
if(op==2)
{
cin>>a>>b;
int now = -a;
vector<int > v;
int suc = 1;
for(int i=1;i<=b;i++)
{
auto val = s2.lower_bound(now);
if(val==s2.end()) suc = 0;
else
{
s2.erase(s2.find(*val));
v.pb(*val);
}
}
if(suc) cout<<-v.back()<<"\n";
else cout<<-1<<"\n";
for(auto t:v) s2.insert(t);
}
if(op==3)
{
cin>>a>>b;
int now = a;
vector<int > v;
int suc = 1;
for(int i=1;i<=b;i++)
{
auto val = s1.lower_bound(now);
if(val==s1.end()) suc = 0;
else
{
s1.erase(s1.find(*val));
v.pb(*val);
}
}
if(suc) cout<<v.back()<<"\n";
else cout<<-1<<"\n";
for(auto t:v) s1.insert(t);
}
}
return 0;
}
迭代:
int T,n,m,k;
int va[N];
multiset<int > s;
signed main()
{
IOS;
cin>>n;
while(n--)
{
int op,a,b;
cin>>op;
if(op==1)
{
cin>>a;
s.insert(a);
}
if(op==2)
{
cin>>a>>b;
auto now = s.upper_bound(a);
if(now==s.begin())
{
cout<<-1<<"\n";
continue;
}
int suc = 1;
for(int i=1;i<=b;i++)
{
now--;
if(now==s.begin())
{
if(i<b) suc = 0;
break;
}
}
if(suc) cout<<*now<<"\n";
else cout<<-1<<"\n";
}
if(op==3)
{
cin>>a>>b;
auto now = s.lower_bound(a);
if(now==s.end())
{
cout<<-1<<"\n";
continue;
}
int suc = 1;
for(int i=1;i<b;i++)
{
now++;
if(now==s.end())
{
suc = 0;
break;
}
}
if(suc) cout<<*now<<"\n";
else cout<<-1<<"\n";
}
}
return 0;
}
总结:
多多积累经验和容器操作。