思路
纯模拟
把前面的数放入两个集合中,第一个集合A是前k小,第二个集合B用来存大一点的数据
最开始加数据:如果A多了,那就把A最后一个放到B
后面更新:首先把这个新的数加在A里面,然后把A最后一个数放在B
然后删去前面的那个数,如果B中有,直接删去。
如果B没有,那就在A中删去,然后把B中的第一个放进来
注意:输出数据的时候要使用迭代器,不然会把所有相同的元素都删去
代码
//直接分成两个集合就可以了,然后判断一下最开始的那个数是在哪一个集合里面的
//如果在后面那个集合,就直接删去
//如果在前面那个集合,就先删去,然后从后面哪一个数过来
//也就是直接暴力模拟
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int M=2e5+5;
int a[M];
multiset<int>st1,st2;
int main() {
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)cin>>a[i];
ll sum=0;
for(int i=1;i<=m;i++) {
sum+=a[i];
st1.insert(a[i]);
if(st1.size()>k) {
st2.insert(*prev(st1.end()));
sum-=*prev(st1.end());
st1.erase(prev(st1.end()));
}
}
//注意删除的时候,只能删一个
//也就是要使用迭代器进行删去
cout<<sum<<' ';
for(int i=m+1;i<=n;i++) {
sum+=a[i];
st1.insert(a[i]);//优先插入第一个
st2.insert(*prev(st1.end()));
sum-=*prev(st1.end());
st1.erase(prev(st1.end()));//把最后一个不要
//查找刚刚那个数
if(st2.find(a[i-m])!=st2.end())st2.erase(st2.find(a[i-m]));
else {
sum-=a[i-m];
st1.erase(st1.find(a[i-m]));
sum+=*(st2.begin());
st1.insert(*(st2.begin()));
st2.erase(st2.begin());
}
cout<<sum<<' ';
}
return 0;
}
//模拟才是第一生产力呀
标签:abc,end,--,int,st1,281,删去,集合
From: https://www.cnblogs.com/basicecho/p/16972486.html