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]<b[i+1]对i<n成立以及a[i]!=a[i+1]
有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<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
    int val,num,pos;
}final[2006000];
vector<int >mp[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<b.val;
}
void find()
{
    int ans=-1;
    int l=0;
    int r=mp[nummaxn].size()-1;
    while(r-l>=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;
            }
        }
    }
}










内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值