题目大意
思路
给所有垃圾的位置排序,并记录下相邻垃圾之间的距离。
每一次询问的答案 = 间隔最远的两堆垃圾的距离 - 最大间隔距。
所以只需要O(log2n)的维护 垃圾的位置信息以及最大间距。
位置信息用set维护,由于可能有多个相等长度的间距,所以用multiset
用法
multiset的用法和set类似。
需要注意的是multiset的erase(x)会删除所有值为x的元素。
删除一个x元素:multiset.erase(multiset.find(x))
即使用erase(迭代器)方法。
判断元素的值否是和结尾相等: x == *–set.end()
AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
set<int>pos;
multiset<int>gap;
void ins(int x){
pos.insert(x);
auto cnt = pos.find(x);
auto l = cnt;
auto r = cnt;
if(l != pos.begin()){
l--;
gap.insert(x - *l);
}
if(r != --pos.end()){
r++;
gap.insert(*r - x);
}
if(cnt != pos.begin() && cnt != --pos.end())gap.erase(gap.find(*r - *l));
}
void era(int x){
auto cnt = pos.find(x);
auto l = cnt;
auto r = cnt;
if(l != pos.begin()){
l--;
gap.erase(gap.find(x - *l));
}
if(r != --pos.end()){
r++;
gap.erase(gap.find(*r - x));
}
if(cnt != pos.begin() && cnt != --pos.end())gap.insert(*r - *l);
pos.erase(x);
}
int solve(){
if(pos.size() < 2)return 0;
else return *--pos.end() - *pos.begin() - *--gap.end();
}
int main(){
int n, m;
cin >> n >> m;
int cnt;
for(int i = 1; i <= n ; i++){
cin >> cnt;
ins(cnt);
}
cout << solve() << endl;
int op, x;
while(m--){
cin >> op >> x;
if(op)ins(x);
else era(x);
cout << solve() << endl;
}
}