STL容器-multiset ABC 170 E

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值