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;
}