ABC 170 E
题目链接:abc 170 E
这道题用到这个容器,由于现学现卖不理解功能于是付出了d三小时bug的教训,代码有注释,bug所在点也已重点标出看代码即可
/*
惨痛教训
multiset删除erase(x)会将所有的x都删除、
而erase(find(x))只会删除一个x
*/
#include<set>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int N = 1e6+5;
struct cmp//重载运算符
{
bool operator()(const int &a, const int &b)
{
return a > b;
}
};
multiset<int,cmp> st[N];//重载后begin()为最大值 存每个幼儿园中最强的人的val
multiset<int> p;//自带的顺序为升序,p.begin()为最小的元素,所有最强的人中最弱的人的val
int a[N],b[N];
int main()
{
int n,q,i,c,d;
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
st[b[i]].insert(a[i]);//将i号人的val存入b[i]号幼儿园中
}
for(i=1;i<=2e5;i++)
{
if(!st[i].empty())
p.insert(*st[i].begin());
}
int val1,val2;
for(i=1;i<=q;i++)
{
scanf("%d%d",&c,&d);
//将c号小孩从b[c]号幼儿园转移到d号幼儿园
val1 = *st[b[c]].begin();//b[c]号幼儿园最强
if(st[d].empty()) val2=0;//d号幼儿园是空的
else val2 = *st[d].begin();//d号幼儿园最强
st[b[c]].erase(st[b[c]].find(a[c]));//将其从原来的幼儿园删除
st[d].insert(a[c]);//将其放入d号幼儿园
if(a[c]==val1)//删去旧的最强,将新的最强放入队列
{
p.erase(p.find(a[c]));
if(!st[b[c]].empty())
p.insert(*st[b[c]].begin());
}
if(a[c]>val2)//小孩是d幼儿园最强的,于是将原来的最强的从最强队列里去除
{
if(val2) p.erase(p.find(val2));
p.insert(a[c]);
}
b[c] = d;//记得更新幼儿园
printf("%d\n",*p.begin());
}
return 0;
}
惨痛教训
multiset删除erase(x)会将所有的x都删除、
而erase(find(x))只会删除一个x