题目大意(源自CF群):
有n<=200000个人参加拍卖一件商品,总共出价n次,但是并不保证一人出价一次,有可能有人没有机会出价。 每一次出价都是一个整数对(a[i],b[i])(a[i]<=n,b[i]<=1e9),a[i]表示出价的人的编号以及b[i]是出价的价格。保证b[i]<b[i+1]对i<n成立以及a[i]!=a[i+1] 有q<=2e5个询问 每一个询问包含一个整数k以及k个人的编号l[j],保证k的总和不会超过2e5 问如果这些人不出现的话,谁会获得这件商品? 对于每一个询问,输出两个整数,胜出者的编号以及胜出者出的价格,如果没有人胜出,输出两个0.
思路:用set<pair<int, int> >pos维护竞价人的下标和最大值,把最大值作为pair里面的第一关键字(因为set自带排序功能),vector<int>lst[N]维护每个竞价人的所有竞价(从小到大)
每次询问,先从pos中删去k个,这个时候有三种情况
1)pos为空,输出0 0
2)pos有一个,输出这唯一一个竞价人的最低报价
3)pos个数大于等于2,找出pos里面第一大竞价人和第二大竞价人,然后在第一大竞价人里找刚好大于第二大竞价人的最大竞价值的值就可以了
可以参考官方题解:http://codeforces.com/blog/entry/49186
解决这类题,要先想清楚怎么解决,用什么数据结构来储存这些数据,
这题的突破口是,拍卖成功者的价位 > 当前拍卖者出钱第二高的那位。。。
储存的时候我要进行贪心优因为删除后这个人多有拍卖记录都要删去,那么当前这个人只要存储他最高的那位,
当然了记录还是要记录一下!!!
#include<bits/stdc++.h> using namespace std; const int N = 200000 + 100; typedef pair<int,int> pii; set<pii>Set; vector<int>vec[N]; int a[N],b[N],vis[N]; int main() { ios::sync_with_stdio(false); int n,i,j,m,id,num,q; cin>>n; for(i=1;i<=n;i++) { cin>>id>>num; vec[id].push_back(num); a[id]=max(a[id],num); vis[id]=1; } for(id=1;id<N;id++) { if(vis[id]) Set.insert({a[id],id}); } cin>>q; while(q--) { cin>>m; for(i=1;i<=m;i++) { cin>>b[i],id=b[i]; if(vis[id]) Set.erase({a[id],id}); } if(Set.size()==0) { cout<<"0 0"<<endl; } else if(Set.size()==1) { set<pii>::iterator it = Set.begin(); id = (*it).second; cout<<id<<" "<<*vec[id].begin()<<endl; } else { set<pii>::iterator it1 = Set.end(); set<pii>::iterator it2 = Set.end(); it1--,it2--,it2--; id=(*it1).second; num=(*it2).first; num=*lower_bound(vec[id].begin(),vec[id].end(),num); cout<<id<<" "<<num<<endl; } for(i=1;i<=m;i++) { id=b[i]; if(vis[id]) Set.insert({a[id],id}); } } return 0; }
