Codeforces Round #388 (Div. 2)D. Leaving Auction(set)
阿新 • • 發佈:2018-11-15
題意:有有許多人蔘加拍賣,問當假定某些人不參加的時候剩餘的人當中誰是最終的贏家,輸出他的編號和最終競價,注:每個人都不能和自己競價,即若某人連續競價兩次,以第一次價格為準。輸入資料保證競價遞增。
思路:
我們只要把每個人競價的最大值存起來, 並且把每個人的所有競價維護在一個有序陣列(方便二分), 對於一組詢問, 我們從大到小遍歷這k個數,把不在這k個數的最終競價最大的兩個人找到(複雜度O(K)), 然後在競價最大的那個人的set裡二分第二大的人的競價最大值就行了。
不能寫:it=ts.end()--;
得寫:
it=ts.end();
it--;
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<set> #include<vector> #include<queue> using namespace std; int n; struct node { int id; int num=0; friend bool operator<(node a,node b) { return a.num<b.num; } }itm[200005]; set<int>s[200005]; set<node>ts; int dc[200005]; int vis[200005]; int main() { while(~scanf("%d",&n)) { for(int i=0;i<=200000;i++) s[i].clear(); ts.clear(); int maxid=0; for(int i=1;i<=n;i++) { int id,num; scanf("%d%d",&id,&num); itm[id].id=id; itm[id].num=num; maxid=max(maxid,id); s[id].insert(num); } for(int i=1;i<=maxid;i++) { ts.insert(itm[i]); } int q; scanf("%d",&q); while(q--) { int m; scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d",&dc[i]); vis[dc[i]]=1; } int ans1=-1,ans2=-1; set<node>::iterator it; set<int>::iterator it1; it=ts.end(); it--; while(1) { int tid=it->id; //cout<<"tid:"<<tid<<":"<<it->num<<endl; if(vis[tid]==0) { if(ans1==-1) { ans1=tid; } else if(ans2==-1 && tid!=ans1) { ans2=tid; break; } } if(it==ts.begin()) { break; } it--; } //cout<<ans1<<" : "<<ans2<<endl; if(ans1==-1 && ans2==-1) { printf("0 0\n"); } else if(ans2==-1) { it1=s[ans1].begin(); printf("%d %d\n",ans1,*it1); } else { it1=s[ans1].upper_bound(itm[ans2].num); printf("%d %d\n",ans1,*it1); } for(int i=0;i<m;i++) { vis[dc[i]]=0; } } } }