Codeforces Round #388 (Div. 2)-D. Leaving Auction

原题链接

D. Leaving Auction
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n people taking part in auction today. The rules of auction are classical. There were n bids made, though it's not guaranteed they were from different people. It might happen that some people made no bids at all.

Each bid is define by two integers (ai, bi), where ai is the index of the person, who made this bid and bi is its size. Bids are given in chronological order, meaning bi < bi + 1 for all i < n. Moreover, participant never makes two bids in a row (no one updates his own bid), i.e. ai ≠ ai + 1 for all i < n.

Now you are curious with the following question: who (and which bid) will win the auction if some participants were absent? Consider that if someone was absent, all his bids are just removed and no new bids are added.

Note, that if during this imaginary exclusion of some participants it happens that some of the remaining participants makes a bid twice (or more times) in a row, only first of these bids is counted. For better understanding take a look at the samples.

You have several questions in your mind, compute the answer for each of them.

Input

The first line of the input contains an integer n (1 ≤ n ≤ 200 000) — the number of participants and bids.

Each of the following n lines contains two integers ai and bi (1 ≤ ai ≤ n, 1 ≤ bi ≤ 109, bi < bi + 1) — the number of participant who made the i-th bid and the size of this bid.

Next line contains an integer q (1 ≤ q ≤ 200 000) — the number of question you have in mind.

Each of next q lines contains an integer k (1 ≤ k ≤ n), followed by k integers lj (1 ≤ lj ≤ n) — the number of people who are not coming in this question and their indices. It is guarenteed that lj values are different for a single question.

It's guaranteed that the sum of k over all question won't exceed 200 000.

Output

For each question print two integer — the index of the winner and the size of the winning bid. If there is no winner (there are no remaining bids at all), print two zeroes.

Examples
input
6
1 10
2 100
3 1000
1 10000
2 100000
3 1000000
3
1 3
2 2 3
2 1 2
output
2 100000
1 10
3 1000
input
3
1 10
2 100
1 1000
2
2 1 2
2 2 3
output
0 0
1 10
把每个人的投标值用vector按照个人存储从小到大存储,把每一个人的投标最大值放在set中,对于每次查询,删除相应的人的投标,若此时set为空,则输出0, 0,若set大小为1,则输出该人投标最小值,若set大小大于1,则找到投标第二大的人投标的的最大值的序数a(也就是第几个投标),再找到投标最大的人的投标值的序数大于a的最小值

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <stack>
#include <cmath>
#include <set>
#define maxn 200005
#define INF 1000000009
typedef long long ll;
using namespace std;

struct Node{
	Node(){
	}
	Node(int a, int b){
		x = a;
		y = b;
	}
	int x, y, p;
	friend bool operator < (const Node&a, const Node&b){
		return a.y < b.y;
	}
};
vector<Node> v[maxn];
vector<int> p;
set<Node> s; 
int main(){
	
//	freopen("in.txt", "r", stdin);
	int n, a, b;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d%d", &a, &b);
		v[a].push_back(Node(a, b));
		v[a][v[a].size()-1].p = i;
	}
	for(int i = 1; i <= n; i++){
		if(v[i].size()){
			s.insert(Node(i, v[i][v[i].size()-1].y));
		}
	}
	int q, k;
	scanf("%d", &q);
	while(q--){
		scanf("%d", &k);
		for(int i = 0; i < k; i++){
			scanf("%d", &a);
			if(v[a].size() == 0)
			 continue;
			p.push_back(a);
			s.erase(s.find(Node(a, v[a][v[a].size()-1].y)));
		}
		if(s.empty())
		  puts("0 0");
		else if(s.size() == 1){
		  int f = s.begin() -> x;
		  printf("%d %d\n", f, v[f][0].y);
	    }
	    else{
	    	set<Node> ::iterator iter = s.end();
	    	iter--;
	    	int f2 = iter -> x;
	    	int f1 = (--iter) -> x;
	    	f1 = v[f1][v[f1].size()-1].p;
	    	int l = 0, r = v[f2].size();
	    	while(l < r){
	    		int mid = (l + r) >> 1;
	    		if(v[f2][mid].p > f1)
	    		 r = mid;
	    		else
	    		 l = mid + 1;
	    	}
	    	printf("%d %d\n", f2, v[f2][l].y);
	    }
	    for(int i = 0; i < p.size(); i++){
	    	s.insert(Node(p[i], v[p[i]][v[p[i]].size()-1].y));
	    }
	    p.clear();
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值