0%

CF-1024-E. 23 Kingdom

思路讲解

不难注意到,你所选择的区间之中,不允许出现两个区间相离的情况。

image

因为这两个区间如果变为相交的话,贡献的答案值一定更大。

由这个结论,那么新加入的区间的 右端点>以前的所有左端点右端点>以前的所有左端点,并且 左端点<以前的所有右端点左端点<以前的所有右端点,因此,所有的左右端点就会分居两端,因为起始的 右端点>左端点右端点>左端点,新加入的 右端点>以前的所有左端点右端点>以前的所有左端点,左端点反之亦然。

image

那么贪心地,我们其实就是想让 il\sum{i_l} 最小, ir\sum{i_r} 最大,那么左端点只要贪心地选择下标小的,右端点我们只要贪心地选择下标大的。

最后一个问题,就是当我们拿到一个序列,如 22342,2,3,4,我们如何知道他是否可以映射到12341,2,3,4 只通过减法。

那么这个其实有一个小的 trick,如果说用加入元素的方法判断,大抵是要用到树状数组或者线段树,但如果使用删除的方法,就可以只用 set 实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
set<ll> st;
auto init=[&](){ // 初始化函数
st.clear();
FOR(i,0,N+1){
st.insert(i);
}
};
auto proc=[&](ll x){ // 处理函数
auto it=st.upper_bound(x);
--it;
if(*it==0){
return false;
}else{
st.erase(it);
return true;
}
};

AC代码

https://codeforces.com/contest/2101/submission/319792559

心路历程(WA,TLE,MLE……)

其实我们的要求是没有任意两个区间相离,这个用线段树判断是有点问题的。

一个比较好的近似解

1
2
3
4
5
6
hack:
1
10
1 1 2 2 3 3 4 4 5 5
ans:
18

https://codeforces.com/contest/2101/submission/319732582