Vova decided to clean his room. The room can be represented as the coordinate axis 𝑂𝑋. There are 𝑛 piles of trash in the room, coordinate of the 𝑖-th pile is the integer 𝑝𝑖. All piles have different coordinates.
Let’s define a total cleanup as the following process. The goal of this process is to collect all the piles in no more than two different 𝑥 coordinates. To achieve this goal, Vova can do several (possibly, zero) moves. During one move, he can choose some 𝑥 and move all piles from 𝑥 to 𝑥+1 or 𝑥−1 using his broom. Note that he can’t choose how many piles he will move.
Also, there are two types of queries:
0 𝑥 — remove a pile of trash from the coordinate 𝑥. It is guaranteed that there is a pile in the coordinate 𝑥 at this moment.
1 𝑥 — add a pile of trash to the coordinate 𝑥. It is guaranteed that there is no pile in the coordinate 𝑥 at this moment.
Note that it is possible that there are zero piles of trash in the room at some moment.
Vova wants to know the minimum number of moves he can spend if he wants to do a total cleanup before any queries. He also wants to know this number of moves after applying each query. Queries are applied in the given order. Note that the total cleanup doesn’t actually happen and doesn’t change the state of piles. It is only used to calculate the number of moves.
For better understanding, please read the Notes section below to see an explanation for the first example.
Input
The first line of the input contains two integers 𝑛 and 𝑞 (1≤𝑛,𝑞≤105) — the number of piles in the room before all queries and the number of queries, respectively.
The second line of the input contains 𝑛 distinct integers 𝑝1,𝑝2,…,𝑝𝑛 (1≤𝑝𝑖≤109), where 𝑝𝑖 is the coordinate of the 𝑖-th pile.
The next 𝑞 lines describe queries. The 𝑖-th query is described with two integers 𝑡𝑖 and 𝑥𝑖 (0≤𝑡𝑖≤1;1≤𝑥𝑖≤109), where 𝑡𝑖 is 0 if you need to remove a pile from the coordinate 𝑥𝑖 and is 1 if you need to add a pile to the coordinate 𝑥𝑖. It is guaranteed that for 𝑡𝑖=0 there is such pile in the current set of piles and for 𝑡𝑖=1 there is no such pile in the current set of piles.
Output
Print 𝑞+1 integers: the minimum number of moves Vova needs to do a total cleanup before the first query and after each of 𝑞 queries.
Examples
inputCopy
5 6
1 2 6 8 10
1 4
1 9
0 6
0 10
1 100
1 50
outputCopy
5
7
7
5
4
8
49
inputCopy
5 8
5 1 2 4 3
0 1
0 2
0 3
0 4
0 5
1 1000000000
1 1
1 500000000
outputCopy
3
2
1
0
0
0
0
0
499999999
Note
Consider the first example.
Initially, the set of piles is [1,2,6,8,10]. The answer before the first query is 5 because you can move all piles from 1 to 2 with one move, all piles from 10 to 8 with 2 moves and all piles from 6 to 8 with 2 moves.
After the first query, the set becomes [1,2,4,6,8,10]. Then the answer is 7 because you can move all piles from 6 to 4 with 2 moves, all piles from 4 to 2 with 2 moves, all piles from 2 to 1 with 1 move and all piles from 10 to 8 with 2 moves.
After the second query, the set of piles becomes [1,2,4,6,8,9,10] and the answer is the same (and the previous sequence of moves can be applied to the current set of piles).
After the third query, the set of piles becomes [1,2,4,8,9,10] and the answer is 5 because you can move all piles from 1 to 2 with 1 move, all piles from 2 to 4 with 2 moves, all piles from 10 to 9 with 1 move and all piles from 9 to 8 with 1 move.
After the fourth query, the set becomes [1,2,4,8,9] and the answer is almost the same (the previous sequence of moves can be applied without moving piles from 10).
After the fifth query, the set becomes [1,2,4,8,9,100]. You can move all piles from 1 and further to 9 and keep 100 at its place. So the answer is 8.
After the sixth query, the set becomes [1,2,4,8,9,50,100]. The answer is 49 and can be obtained with almost the same sequence of moves as after the previous query. The only difference is that you need to move all piles from 50 to 9 too.
题意:
有一些点有东西,要求你指定两个洞,然后把每个点的东西依次移动到洞里(东西如果在一个点可以合并)。求最小操作次数。
然后还有删除东西和加东西的操作。
思路:
很明显洞直接放在两边就好了,所以结果就是东西的左右距离减去中间两个相邻东西最大距离。用set维护这个最大距离就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;
int a[maxn];
map<int,int>mp;
set<int>st;//所有的值
multiset<int>mst;//所有的间距
int main() {
int n,q;scanf("%d%d",&n,&q);
for(int i = 1;i <= n;i++) {
scanf("%d",&a[i]);
mp[a[i]]++;
st.insert(a[i]);
}
sort(a + 1,a + 1 + n);
int mx = 0;
for(int i = 2;i <= n;i++) {
mst.insert(a[i] - a[i - 1]);
}
if(st.size() <= 1) printf("0\n");
else {
mx = *(--mst.end());
printf("%d\n",a[n] - a[1] - mx);
}
for(int i = 1;i <= q;i++) {
int t,x;scanf("%d%d",&t,&x);
if(t == 1) {
if(mp[x] == 0) {
auto it = st.lower_bound(x);
int pre = 0,nex = 0;
if(it != st.end()) { //后继
nex = *it;
mst.insert(nex - x);
}
if(it != st.begin()) { //前驱
pre = *(--it);
mst.insert(x - pre);
}
if(nex && pre) mst.erase(mst.find(nex - pre));
st.insert(x);
}
mp[x]++;
} else {
if(mp[x] == 1) {
auto it = st.find(x);
int pre = 0,nex = 0;
if(++it != st.end()) { //后继
nex = *it;
mst.erase(mst.find(nex - x));
}
--it;
if(it != st.begin()) { //前驱
pre = *(--it);
mst.erase(mst.find(x - pre));
}
if(pre && nex) mst.insert(nex - pre);
st.erase(st.find(x));
}
mp[x]--;
}
if(st.size() <= 1) {
printf("0\n");
continue;
}
mx = *(--mst.end());
printf("%d\n",*(--st.end()) - *(st.begin()) - mx);
}
return 0;
}
本文介绍了一种垃圾清理算法,目标是在二维坐标系中将所有垃圾堆集中到两个不同的x坐标上,通过最少的移动次数实现。文章详细解释了算法的运行过程,包括如何处理垃圾堆的添加和移除操作,以及如何计算每次操作后的最小移动次数。
430

被折叠的 条评论
为什么被折叠?



