Leaving Auction

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\n");
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\n",temp[0],it);
46         }else if(num==1){
47             printf("%d %d\n",temp[0],man[temp[0]][0]);
48         }
49     }
50 }

 

posted @ 2016-12-21 02:37  barriery  阅读(218)  评论(0编辑  收藏  举报