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 weren 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), whereai is the index of the person, who made this bid andbi is its size. Bids are given in chronological order, meaningbi < bi + 1 for alli < n. Moreover, participant never makes two bids in a row (no one updates his own bid), i.e.ai ≠ ai + 1 for alli < 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 integersai andbi (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 integerk (1 ≤ k ≤ n), followed byk 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 exceed200 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
Note

Consider the first sample:

  • In the first question participant number 3 is absent so the sequence of bids looks as follows:
    1. 1 10
    2. 2 100
    3. 1 10 000
    4. 2 100 000
    Participant number 2 wins with the bid 100 000.
  • In the second question participants 2 and 3 are absent, so the sequence of bids looks:
    1. 1 10
    2. 1 10 000
    The winner is, of course, participant number 1 but the winning bid is10 instead of 10 000 as no one will ever increase his own bid (in this problem).
  • In the third question participants 1 and 2 are absent and the sequence is:
    1. 3 1 000
    2. 3 1 000 000
    The winner is participant 3 with the bid 1 000

题目大意(源自CF群):

有n<=200000个人参加拍卖一件商品,总共出价n次,但是并不保证一人出价一次,有可能有人没有机会出价。
每一次出价都是一个整数对(a[i],b[i])(a[i]<=n,b[i]<=1e9),a[i]表示出价的人的编号以及b[i]是出价的价格。保证b[i] 有q<=2e5个询问
每一个询问包含一个整数k以及k个人的编号l[j],保证k的总和不会超过2e5
问如果这些人不出现的话,谁会获得这件商品?
对于每一个询问,输出两个整数,胜出者的编号以及胜出者出的价格,如果没有人胜出,输出两个0.


思路:


1、观察到关于询问K,删除的所有ID的和不超过200000这个条件我们可以推出,最极限的情况,我们也就有400+个ID.那么我们考虑进行暴力,对应输入进来的所有出价,我们维护每个人的最高出价(因为保证输入递增,那么我们只要维护最后一次输入进来的出价即可);然后我们将其按照从大到小排序,那么对应我们找到胜利者很容易,只要枚举出第一个没有被删除的人即可。那么此时操作时间复杂度约为O(400*q);


2、因为我们此时已经很容易的找到了胜利者,那么我们接下来需要判断这个胜利者的胜利价格,那么对应我们还需要找到第二大的出价人,对应找到他的最大出价,那么接下来我们只要找到胜利者的第一个大于这个最高出价的出价,那么这个价格就是胜利的者的胜利出价。,那么我们对应维护一个vector,其中存入每个人的出价,按照输入的顺序,因为题目保证每个出价都是递增的,那么其具有单调性,那么接下来我们二分这个价值即可。总时间复杂度越位O(400*q*logn);


3、实现代码细节比较多,注意没有胜者和只有一个出价人的情况的处理。


Ac代码:

#include
#include
#include
#include
using namespace std;
struct node
{
    int val,num,pos;
}final[2006000];
vectormp[250006];
int num[200600];
int val[200600];
int a[250006];
int vis[250006];
int n,cont,maxn,minn,nummaxn;
int cmp(node a,node b)
{
    return a.val=0)
    {
        int mid=(l+r)/2;
        if(mp[nummaxn][mid]>=minn)
        {
            ans=mp[nummaxn][mid];
            r=mid-1;
        }
        else l=mid+1;
    }
    printf("%d\n",ans);
}
void Slove()
{
    int cnt=0;
    nummaxn=-1;
    maxn=-1,minn=-1;
    for(int i=n;i>=1;i--)
    {
        if(vis[final[i].num]==1)continue;
        if(final[i].val==0)break;
        if(cnt==0)
        {
            maxn=final[i].val;
            cnt++;
            nummaxn=final[i].num;
        }
        else
        {
            if(nummaxn==final[i].num)continue;
            else
            {
                minn=final[i].val;
                cnt++;
            }
        }
        if(cnt==2)break;
    }
    if(nummaxn==-1)
    {
        printf("0 0\n");
        return ;
    }
    printf("%d ",nummaxn);
    find();
}
int main()
{
    while(~scanf("%d",&n))
    {
        cont=0;
        memset(final,0,sizeof(final));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)mp[i].clear();
        for(int i=1;i<=n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            final[x].val=y;
            final[x].pos=i;
            final[x].num=x;
            num[i]=x;val[i]=y;
            mp[x].push_back(y);
        }
        sort(final+1,final+n+1,cmp);
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int k;
            scanf("%d",&k);
            for(int i=1;i<=k;i++)
            {
                scanf("%d",&a[i]);
                vis[a[i]]=1;
            }
            Slove();
            for(int i=1;i<=k;i++)
            {
                vis[a[i]]=0;
            }
        }
    }
}










你可能感兴趣的:(思维,二分查找,2)