Leaving Auction
题目链接:http://codeforces.com/contest/749/problem/D
二分
本来以为是哪种神奇的数据结构,没想到sort+lower_bonud就解决了,妙。
这道题的精髓在于将每个人出价的最大值记录下来,最后竞拍到的一定为没有leave的人中出价最高的那个人(因为It's guaranteed that the sum of k over all question won't exceed 200 000. 所以这个操作的总复杂度不会超过200 000)。而这个人的最低出价,只需要比第二个人的最高出价高即可,此操作可以用二分。//最后不得不说scanf和cin在没有关同步之前,差别真的很大...
代码如下:
1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #include <algorithm> 5 #include <set> 6 #define pb(x) push_back(x) 7 #define N 200005 8 using namespace std; 9 int n,q,k,t,biggest[N],person[N]; 10 vector<int>man[N]; 11 bool cmp(int a,int b){ 12 return biggest[a]<biggest[b]; 13 } 14 int main(void){ 15 scanf("%d",&n); 16 for(int i=1;i<=n;++i){ 17 int a,b; 18 scanf("%d%d",&a,&b); 19 man[a].pb(b); 20 biggest[a]=b; 21 person[i]=i; 22 } 23 sort(person+1,person+1+n,cmp); 24 scanf("%d",&q); 25 while(q--){ 26 set<int>leave; 27 scanf("%d",&k); 28 for(int i=0;i<k;++i){ 29 scanf("%d",&t); 30 leave.insert(t); 31 } 32 int temp[2],num=0; 33 temp[0]=temp[1]=0; 34 for(int i=n;i>=1;--i){ 35 if(leave.count(person[i]))continue; 36 temp[num++]=person[i]; 37 if(num==2)break; 38 } 39 if(man[temp[0]].size()==0){ 40 printf("0 0 "); 41 continue; 42 } 43 if(num==2){ 44 int it=*lower_bound(man[temp[0]].begin(),man[temp[0]].end(),biggest[temp[1]]); 45 printf("%d %d ",temp[0],it); 46 }else if(num==1){ 47 printf("%d %d ",temp[0],man[temp[0]][0]); 48 } 49 } 50 }