题意:拍卖一件物品,有n个竞标,一个人可以有多个竞标。给出n个竞标,a[i],b[i].a[i]表示人的序号,b[i]表示竞标价格。接下来有q个询问,每次一个k,之后k个数表示该序号的人缺席。问谁最终以多少钱得标。如果没有输出0 0,否则输出序号和价钱。
思路:按竞标价格排个序 然后删除那些缺席人 找到竞标价格第一大和第二大的 用二分找到第一大的人中投标的价格大于第二大投标的最大价格,用set删。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<queue> #include<vector> #include<string> #include<set> #define ll long long using namespace std; const int N=500000+100; struct point { int maxx=0; int pos; }a[N]; vector<int> v[N]; set<pair<int,int> >aa,bb; int vis[N]; int b[N]; int check(int x,int y) { int i=v[y].size()-1; int tt=v[y][i]; int n=v[x].size(); int r=upper_bound(v[x].begin(),v[x].end(),tt)-v[x].begin(); return v[x][r]; } int main() { int n; int x,y; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); a[i].maxx=y; a[i].pos=x; v[x].push_back(y); } for(int i=n;i>=1;i--) { if(vis[a[i].pos]==0) { aa.insert(make_pair(-i,a[i].pos)); vis[a[i].pos]=i; } } set<pair<int,int> >::iterator it; int t; scanf("%d",&t); while(t--) { int m; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d",&x); b[i]=x; if(vis[x]==0) continue; aa.erase(make_pair(-vis[x],a[vis[x]].pos)); } if(aa.size()==0) { printf("0 0 "); } else if(aa.size()==1) { int t=aa.begin()->second; int t1=v[t][0]; printf("%d %d ",t,t1); } else { int t=aa.begin()->second; int t1=(++aa.begin())->second; printf("%d %d ",t,check(t,t1)); } for(int i=1;i<=m;i++) { x=b[i]; if(vis[x]) { aa.insert(make_pair(-vis[x],a[vis[x]].pos)); } } } }