P10144 [WC/CTS2024] 水镜

对于任何一段连续上升的区间,我们不需要管它。对于任何一段连续下降的区间,我们只需要用 \(2L\) 减去每个数就可以化为一段连续上升的区间。因此,对于这两种区间,我们可以看作一个点。

于是,我们发现其实 \(2L\) 只会被波峰 \(a_{i}\ge a_{i-1},a_{i}\ge a_{i+1}\) 和波谷 \(a_{i}\le a_{i-1},a_{i}\le a_{i+1}\) 限制住。我们考虑对于每个波峰和波谷,是否存在一种方式可以走过去。

对于一个波峰 \(a_{i}\ge a_{i-1},a_{i}\ge a_{i+1}\),我们有两种方法:

第一种,\(a_{i+1}\to2L-a_{i+1}\),这样就得满足 \(2L-a_{i+1}\gt a_{i}\),即 \(2L\gt a_{i}+a_{i+1}\)。

第二种,\(a_{i}\to2L-a_{i}\) 且 \(a_{i+1}\to2L-a_{i+1}\),这种情况下显然 \(a_{i+1}\gt a_i\)。但是这样就得满足 \(2L-a_{i}\gt a_{i-1}\),即 \(2L\gt a_{i}+a_{i-1}\)。

如果 \(2L\gt a_{i}+\min(a_{i-1},a_{i+1})\),则一定存在上述两种方法中的一种可以走过这个波峰。

对于一个波谷 \(a_{i}\le a_{i-1},a_{i}\le a_{i+1}\),我们有两种方法:

第一种,\(a_{i-1}\to2L-a_{i-1}\) 且 \(a_{i}\to2L-a_{i}\),这种情况下显然 \(a_{i}\gt a_{i-1}\)。这样就得满足 \(2L-a_{i}\lt a_{i+1}\),即 \(2L\lt a_{i}+a_{i+1}\)。

第二种,\(a_{i}\to2L-a_{i}\),这样就得满足 \(2L-a_{i}\lt a_{i-1}\),即 \(2L\lt a_{i}+a_{i-1}\)。这里不需要管对 \(a_{i+1}\) 的影响,因为在下一个波峰中会统计。

如果 \(2L\lt a_{i}+\max(a_{i-1},a_{i+1})\),则一定存在上述两种方法中的一种可以走过这个波谷。

对于波峰套波峰或波峰套波谷一类的情况,这样也是对的。原因是这样的限制给了每个波峰和波谷两种选择方式,套起来的两个波峰或波谷一定有一种方式可以匹配。

最后,我们发现合法的区间可以使用双指针维护。上面的这些限制可以使用 multiset 来维护,支持插入,删除,查询最值。

时间复杂度 \(O(n\log n)\),非常优秀。

#include <bits/stdc++.h>
using namespace std;
long long n,a[600000],ans=0,j=3;
multiset<long long>b,s;
void add(long long x)
{
if(x==n)return;
if(a[x]>=a[x-1]&&a[x]>=a[x+1])s.insert(-a[x]-min(a[x-1],a[x+1]));
if(a[x]<=a[x-1]&&a[x]<=a[x+1])b.insert(a[x]+max(a[x-1],a[x+1]));
} void del(long long x)
{
if(x==n)return;
if(a[x]>=a[x-1]&&a[x]>=a[x+1])s.erase(s.find(-a[x]-min(a[x-1],a[x+1])));
if(a[x]<=a[x-1]&&a[x]<=a[x+1])b.erase(b.find(a[x]+max(a[x-1],a[x+1])));
} int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
add(2);
for(int i=1;i<=n;i++)
{
if(i!=1)del(i);
while((b.empty()||s.empty()||*b.begin()>-(*s.begin()))&&j<=n)add(j),j++;
ans+=(j-i);
}
printf("%lld\n",ans-n);
return 0;
}

Luogu P10144 [WC/CTS2024] 水镜 题解的更多相关文章

  1. SCOI2014极水的题解- -

    话说SCOI都考了1个月了,终于拿出决心把题解补完了,但都说了是极水的题解,大家就看着玩吧- - DAY1 T1:目标是找最长不降子序列,先就有一个比较显然的结论,就是假如我们要拔高区间[L, R], ...

  2. bzoj usaco 金组水题题解(2)

    续.....TAT这回不到50题编辑器就崩了.. 这里塞40道吧= = bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 比较经典的最小割?..然而 ...

  3. Luogu 1093 - 奖学金 - [排序水题]

    题目链接:https://www.luogu.org/problemnew/show/P1093 题目描述某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生 ...

  4. Luogu USACO Training 刷水记录

    开个坑记录一下刷USACO的Training的记录 可能会随时弃坑 只有代码和做法简述 可能没有做法简述 [USACO1.1]你的飞碟在这儿Your Ride Is He… 模拟,细节已忘 #incl ...

  5. 【luogu P1640 [SCOI2010]连续攻击游戏】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1640 数据有点水吧,从属性值连向对应武器编号. 枚举属性值匹配,遇到第一个无法匹配的直接跳出就好惹~. #i ...

  6. World Finals 2017 (水题题解)

    看大佬做2017-WF,我这种菜鸡,只能刷刷水题,勉强维持生活. 赛后补补水题. 题目pdf链接,中文的,tls翻译的,链接在这里 个人喜欢在vjudge上面刷题. E Need for Speed ...

  7. NOIP 模拟赛 day5 T2 水 故事题解

    题目描述 有一块矩形土地被划分成 \(\small n×m\) 个正方形小块.这些小块高低不平,每一小块都有自己的高度.水流可以由任意一块地流向周围四个方向的四块地中,但是不能直接流入对角相连的小块中 ...

  8. bzoj usaco 金组水题题解(2.5)

    bzoj 2197: [Usaco2011 Mar]Tree Decoration 树形dp..f[i]表示处理完以i为根的子树的最小时间. 因为一个点上可以挂无数个,所以在点i上挂东西的单位花费就是 ...

  9. bzoj usaco 金组水题题解(1)

    UPD:我真不是想骗访问量TAT..一开始没注意总长度写着写着网页崩了王仓(其实中午的时候就时常开始卡了= =)....损失了2h(幸好长一点的都单独开了一篇)....吓得赶紧分成两坨....TAT. ...

  10. 络谷AT941(水提高+)题解

    蒟蒻刷水题的日常 这个题虽然模拟也不会超时,但我不喜欢模拟,能不模拟就不模拟,容易超时. 接下来进入正题: 实际上一开始是个很无聊的过程,你拿点,我拿点....贼无聊.我们可以把这个过程去掉.只看最后 ...

随机推荐

  1. Python科学计算系列7—微分方程

    1.可分离变量方程 例1:求下列微分方程法通解 先化简此方程如下: 代码如下: from sympy import * x = symbols('x') f = symbols('f', cls=Fu ...

  2. 🎀Charles激活

    简介 Charles激活码计算 激活 Help -> Register Charles 添加 Registered Name 和计算出的 License key 点击 Register Java ...

  3. python之random函数,随机取值

    如 a =['辣椒炒肉','红烧肉','剁椒鱼头','酸辣土豆丝','芹菜香干'] 需要从a数组中随机取出一个值打印出来 具体脚本 import random a =['辣椒炒肉','红烧肉','剁椒 ...

  4. 如何在 MySQL 中实现读写分离?

    如何在 MySQL 中实现读写分离? 在 MySQL 中实现读写分离主要目的是为了提升数据库的性能和扩展性,将读请求和写请求分配到不同的服务器上,减轻主数据库的压力.通常,写请求会发送到主库,而读请求 ...

  5. MySQL 的 Change Buffer 是什么?它有什么作用?

    MySQL 的 Change Buffer 1. 什么是 Change Buffer? Change Buffer 是 MySQL InnoDB 存储引擎中的一个优化机制,用于减少磁盘 I/O 操作. ...

  6. js判断对象任意深度的key属性是否存在,js的iset方法

    ​ 方法一: 支持纯对象的obj // isset.js module.exports = (obj, keyPath) => { const keys = keyPath.split('.') ...

  7. 适用于LixtBox的,开启UI虚拟化时,某些时候需要定位到还没加载的项,比如自动选中某项,视图自动移过去等等

    1 /// <summary> 2 /// 将指定父级的下级索引元素,显示在视野下,使其可见 3 /// </summary> 4 /// <param name=&qu ...

  8. 微信支付功能的设计实现与关键实践(UniApp+Java)全代码

    感觉本篇对你有帮助可以关注一下我的微信公众号(深入浅出谈java),会不定期更新知识和面试资料.技巧!!! 温馨提醒:阅读时可打开导航栏 概述 在移动互联网时代,支付功能已成为应用开发的核心能力之一. ...

  9. 【安装】Linux下安装CUDA ToolKit 11.4和cuDNN 8

    注意!如果你使用的是pytorch,只需要装好CUDA,不需要装cuDNN.而且完全可以等到报错了再装CUDA,一般情况系统都已经装好CUDA Toolkit了. 除非你只装了低版本的CUDA Too ...

  10. P1514 [NOIP 2010 提高组] 引水入城 题解

    题意:P1514 [NOIP 2010 提高组] 引水入城有点复杂,自己看吧. 思路 这里提供一个好像没见过的纯 DP 做法,不需要神秘的证明以及任何脑子,直接顺着思路做即可. 首先判断正确性就是从第 ...