Codeforces Round #388 (Div. 2) D . Leaving Auction
题意很简单,就是卡时间,首先你要知道set的有序性,唯一性,查找搜索都是O(logN)的时间,由复杂度可以大概推算时间。
每个人的最大出价要数组maxprice 存起来,每个人的每一次出价用set存起来,以便找到最小价格。询问之前,先构造一个最大价格集合set< pair< int,int > >, 前面是价格,后面是人编号。
每次询问,先删除,后插回,题目保证q次询问的所有K加起来不超过200000
下面是代码,483ms
#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
const int maxn = 200005;
int maxprice[maxn]={0},a[maxn];
set<int> peo[maxn];//everyone's bids' list
set<pair<int,int > > allbid;//set是有序的,按小到大排,存pair的话,按first的值排序
//每次询问的删除、插入,先判断可以节省时间,而不是都是k
int main()
{
int n;
scanf("%d",&n);
int num,price;
for(int i=1;i <= n;++i){
scanf("%d %d",&num,&price);
peo[num].insert(price);
maxprice[num] = price;
}
for(int i=1;i <= n;++i){
if(maxprice[i])
allbid.insert(make_pair(maxprice[i],i));
}
int q,k;
scanf("%d",&q);
set<pair<int,int> >::iterator it;
while(q--){//O( (sum of ki) * log n), log 200000 ~= 18
scanf("%d",&k);
int t;
for(int j=1;j<=k;++j){//ki log n
scanf("%d",&t);
a[j] = t;
if(maxprice[t])
allbid.erase(make_pair(maxprice[t],t));
}
if(allbid.size()==0)printf("0 0\n");
else {
it = allbid.end();
it--;
int winp = (*it).second;
if(allbid.size()==1)printf("%d %d\n",winp,*(peo[winp].begin()));
else {
it--;
int secV = (*it).first;
printf("%d %d\n",winp,*(peo[winp].upper_bound(secV) ));
}
}
for(int j=1;j<=k;++j){//ki log n
t = a[j];
if(maxprice[t])
allbid.insert(make_pair(maxprice[a[j]],a[j]));
}
}
return 0;
}