题意

数轴上有 \(n\) 个点,每一次你可以将所有位置在 \(x\) 的点移动到 \(x-1\) 或者是移动到 \(x+1\),花费为 \(1\)。

有 \(q\) 次操作,每一次会在数轴上添加一个原来没有的点或者是删除一个原来已经有的点。在所有操作前和每一次操作后你需要回答将所有点集中到不超过两个点的最小花费。

\(\texttt{Data Range:}1\leq n,q\leq 10^5\)

前言

你打开了本题。

你发现是已经写过了 \(998244353\) 遍的维护最大的邻项之差。

你熟练的写出了代码,但是发现需要分类讨论,很头疼。

你翻开了题解,发现题解也是分类讨论。

相信经历了这么多的你心中满满的“我太难了”。

那么这篇题解将拯救你于水火之中(?)

题解

注意到肯定是左边一段的点放在一起右边一段的点放在一起。

假设当前一共有 \(n\) 个点,从小到大依次为 \(p_1,\cdots,p_n\),考虑让 \(p_1,\cdots,p_k\) 放在一起,\(p_{k+1},\cdots,p_n\) 放在一起,那么花费为 \(p_k-p_1+p_n-p_{k+1}=(p_n-p_1)-(p_{k+1}-p_k)\)。

注意到对于每一个加点删点的操作来说 \(p_n-p_1\) 很容易维护,然后 \(p_{k+1}-p_k\) 就是开个 multiset 维护最大差值就完了。

但是这东西需要分类讨论很麻烦,所以我们想个办法让维护这东西变得很轻松不需要分类讨论。

考虑 Splay 预处理的时候往里面加 \(\infty\) 和 \(-\infty\),所以我们也可以往里面加 \(\infty\) 和 \(-\infty\)。

然后询问的时候最大的两个绝对是 \(p_1-(-\infty)\) 和 \(\infty-p_n\),于是只需要查询第三大的那个就好了,没有第三大的答案就是 \(0\)。

这么写可以规避各种各样的分类讨论,比如说什么新插入的值没有前驱后继啦,什么插入点之前 multiset 里元素不够啦什么的,何乐而不为呢?

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll MAXN=2e5+51,inf=1e15;
multiset<ll>st,gap;
multiset<ll>::iterator it;
ll n,qcnt,op,u,prv,nxt,mx,mn;
ll x[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline void erase(ll x)
{
gap.erase(gap.find(x));
}
inline ll query()
{
if(*gap.begin()>=1e12)
{
return 0;
}
it=st.begin(),mn=*(++it),it=st.end(),--it,mx=*(--it);
return it=gap.end(),--it,--it,mx-mn-*(--it);
}
int main()
{
n=read(),qcnt=read(),st.insert(inf),st.insert(-inf);
for(register int i=1;i<=n;i++)
{
st.insert(x[i]=read());
}
sort(x+1,x+n+1),x[0]=-inf,x[n+1]=inf;
for(register int i=1;i<=n+1;i++)
{
gap.insert(x[i]-x[i-1]);
}
printf("%lld\n",query());
for(register int i=0;i<qcnt;i++)
{
op=read(),u=read();
if(op==0)
{
it=st.find(u),prv=u-*(--it),it++,nxt=*(++it)-u;
st.erase(u),erase(prv),erase(nxt),gap.insert(nxt+prv);
}
if(op==1)
{
it=st.upper_bound(u),nxt=*(it--),prv=*it,st.insert(u);
erase(nxt-prv),gap.insert(nxt-u),gap.insert(u-prv);
}
if(*gap.begin()>=1e12)
{
puts("0");
continue;
}
printf("%lld\n",query());
}
}

CodeForces 1418D Trash Problem的更多相关文章

  1. codeforces 340C Tourist Problem

    link:http://codeforces.com/problemset/problem/340/C 开始一点也没思路,赛后看别人写的代码那么短,可是不知道怎么推出来的啊! 后来明白了. 首先考虑第 ...

  2. codeforces B. Routine Problem 解题报告

    题目链接:http://codeforces.com/problemset/problem/337/B 看到这个题目,觉得特别有意思,因为有熟悉的图片(看过的一部电影).接着让我很意外的是,在纸上比划 ...

  3. Codeforces 527D Clique Problem

    http://codeforces.com/problemset/problem/527/D 题意:给出一些点的xi和wi,当|xi−xj|≥wi+wj的时候,两点间存在一条边,找出一个最大的集合,集 ...

  4. Codeforces 706C - Hard problem - [DP]

    题目链接:https://codeforces.com/problemset/problem/706/C 题意: 给出 $n$ 个字符串,对于第 $i$ 个字符串,你可以选择花费 $c_i$ 来将它整 ...

  5. Codeforces 1096D - Easy Problem - [DP]

    题目链接:http://codeforces.com/problemset/problem/1096/D 题意: 给出一个小写字母组成的字符串,如果该字符串的某个子序列为 $hard$,就代表这个字符 ...

  6. Codeforces 793C - Mice problem(几何)

    题目链接:http://codeforces.com/problemset/problem/793/C 题目大意:给你一个捕鼠器坐标,和各个老鼠的的坐标以及相应坐标的移动速度,问你是否存在一个时间点可 ...

  7. CodeForces 687A NP-Hard Problem

    Portal:http://codeforces.com/problemset/problem/687/A 二分图染色 好模板题 有SPJ 值得注意的是,因为C++的奇妙的运算机制 若在vector变 ...

  8. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

  9. Codeforces Gym 100342C Problem C. Painting Cottages 转化题意

    Problem C. Painting CottagesTime Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

随机推荐

  1. java原生程序redis连接(连接池/长连接和短连接)选择问题

    最近遇到的连接问题我准备从重构的几个程序(redis和mysql)长连接和短连接,以及连接池和单连接等问题用几篇博客来总结下. 这个问题的具体发生在java原生程序和redis的交互中.这个问题对我最 ...

  2. package.json 非官方字段集合

    package.json 非官方字段集合 package.json 官方字段请参考 https://docs.npmjs.com/files/package.json.下面介绍的是非官方字段,也就是各 ...

  3. 帮你理清React的生命周期

    这是一个从印记中文 | react官方文档提取总结的,算是帮自己理清并且强化记忆React的生命周期,以便以后编写组件的时候能够有更清晰的思路.本文如有纰漏,欢迎指正 整体上来讲,React生命周期分 ...

  4. java调用Oracle中的存储过程与存储函数

    1 //调用存储过程 2 public static void testPro(){ 3 String driver = "oracle.jdbc.OracleDriver"; 4 ...

  5. Centos-搜索文件或目录-find

    find 在指定的目录下查找指定的文件 相关选项 -type 指定文件类型 -name   指定文件名字,支持通配符 -gid   指定用户组ID -uid   指定用户ID -empty 查找长度为 ...

  6. training set, validation set, test set的区别

    training set: 用来训练模型 validation set : 用来做model selection test set : 用来评估所选出来的model的实际性能 我们知道,在做模型训练之 ...

  7. Python练习题 031:Project Euler 003:最大质因数

    本题来自 Project Euler 第3题:https://projecteuler.net/problem=3 # Project Euler: Problem 3: Largest prime ...

  8. 怎么摆脱又臭又长的 Git 命令?

    在使用 Git 的时候,虽然大部分时候我们用的是图形客户端,但图形客户端不能解决所有的操作,所以,也少不了要需要使用命令行的时候. 但有些 Git 命令和参数确实又不好记,甚至有的命令每次要用的时候需 ...

  9. C 多态 RT-Thread

    // RT-Thread对象模型采用结构封装中使用指针的形式达到面向对象中多态的效果,例如: // 抽象父类 #include <stdio.h> #include <assert. ...

  10. Lyndon Word相关

    Lyndon Word 定义 对于字符串 \(S\),若 \(S\) 的最小后缀为其本身,那么称 \(S\) 为 \(\text{Lyndon}\) 串(\(\text{Lyndon Word}\)) ...