USACO 2017 DEC SILVER

B
题面:有n个起始为g的数,在m天里每天都会对其中一个数进行调整(加或减),而你要维护一个最大值列表,包括所有为当前最大值的数的编号。问此列表要改变的次数。
n<=1e9,m<=1e6
从数据范围可以看出,我们无法也不需要对每一个数进行维护,仅需对可能发生改变的1e6个数维护即可,那么为了建立每一个编号及其值之间的关系,可以用map来进行维护
那么接下来的重点就在于如何维护这些已经改变过的数的最大值,以及当前最大值的个数
一开始我并未使用数据结构,直接对最大值,次大值进行维护,但实际上当上一步的最大值进行减法时,需要再进行一次排序,因此不可行
实际上map中也是有自带的排序的,默认map<int,int,less >,从而我们也可以使用greater来使其降序排列,并用map.begin()来调取其最大的键所对应的值
同时,map本身内部的数据结构又是pair性质的,因此有了iterator:map.begin()后,可以使用map.begin()->first调取键,用map.begin()->second调取值
这样,我们就可以再用一个map来表示当前每种值所对应的数的个数

#include <bits/stdc++.h>
using namespace std;
struct milk
{
    int day,num,change;
}dat[100005];
int n,g;
map<int,int> mp;
map<int,int,greater<int> > cnt;
bool cmp(milk p,milk q)
{
    return p.day<q.day;
}
int main()
{    
    cin >> n >> g;
    for(int i=1;i<=n;i++)
    {
        cin >> dat[i].day >> dat[i].num >> dat[i].change;
        if(!mp.count(dat[i].num)) mp[dat[i].num]=g;
    } 
    sort(dat+1,dat+n+1,cmp);
    int res=0;cnt[g]=n;
    for(int i=1;i<=n;i++)
    {
        int last=mp[dat[i].num];mp[dat[i].num]+=dat[i].change;
        int lmax=cnt.begin()->first,lcnt=cnt.begin()->second; 
        if(cnt[last]==1) cnt.erase(last); 
        else cnt[last]--;
        cnt[mp[dat[i].num]]++;
        if(last==lmax)
        { 
            if(mp[dat[i].num]==cnt.begin()->first && cnt[mp[dat[i].num]]==1 && lcnt==1) continue;
            res++;
        }
        else if(mp[dat[i].num]>=lmax) res++;
    }
    cout << res;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值