Loading

Codeforces 749D:Leaving Auction(set+二分)

http://codeforces.com/contest/749/problem/D

题意:有几个人在拍卖场竞价,一共有n次喊价,有q个询问,每一个询问有一个num,接下来num个人从这次拍卖中除去,问对于每一个询问减掉num个人后是谁赢了拍卖,最小的价格是多少。

思路:昨晚不会做。想法好神奇(我太弱)。对于每个人用 set-S 装起来其每次喊价的下标,然后用一个数组order按价格从大到小的顺序将每个人装起来,对于每一个询问,把这num个人丢到一个 set-s 里面,然后在order里面找没出现过在 s 里面的,那么这个人 x 就是这场拍卖的胜者,那么还要考虑他喊的最低价格,将 x 也丢到 s 里面,再找一个 y,这个 y 是第二个大的,所以在 S[x] 里面二分找大于 y 喊过的最大价格就是答案了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <string>
 7 #include <iostream>
 8 #include <stack>
 9 #include <map>
10 #include <queue>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 #define N 200010
15 #define INF 0x3f3f3f3f
16 bool vis[N];
17 int v[N][2];
18 vector<int> order;
19 set<int> S[N];
20 
21 int main()
22 {
23     int n;
24     cin >> n;
25     for(int i = 0; i < n; i++) {
26         scanf("%d%d", &v[i][0], &v[i][1]);
27         S[v[i][0]].insert(i);
28     }
29     for(int i = n - 1; i >= 0; i--) {
30         if(!vis[v[i][0]]) {
31             vis[v[i][0]] = 1;
32             order.push_back(v[i][0]);
33         }
34     }
35     int q;
36     cin >> q;
37     while(q--) {
38         set<int> s;
39         int num;
40         scanf("%d", &num);
41         while(num--) {
42             int k;
43             scanf("%d", &k);
44             s.insert(k);
45         }
46         int x = -1, y = -1;
47         for(int i = 0; i < order.size(); i++) {
48             if(s.find(order[i]) == s.end()) {
49                 x = order[i];
50                 break;
51             }
52         }
53         if(x == -1) puts("0 0");
54         else {
55             s.insert(x);
56             for(int i = 0; i < order.size(); i++) {
57                 if(s.find(order[i]) == s.end()) {
58                     y = order[i];
59                     break;
60                 }
61             }
62             if(y == -1) {
63                 printf("%d %d\n", x, v[*S[x].begin()][1]);
64             } else {
65                 set<int>::iterator it = S[y].end();
66                 int pos = *(--it);
67                 it = S[x].upper_bound(pos);
68                 printf("%d %d\n", x, v[*it][1]);
69             }
70         }
71     }
72     return 0;
73 }

 

posted @ 2016-12-20 13:31  Shadowdsp  阅读(414)  评论(0编辑  收藏  举报