当前位置: 首页 > article >正文

AtCoder AT_abc406_c [ABC406C] ~

前言

除了 A 题,唯一一道一遍过的题。

题目大意

我们定义满足以下所有条件的一个长度为 N N N 的序列 A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\dots,A_N) A=(A1,A2,,AN)波浪序列

  • N ≥ 4 N\ge4 N4(其实满足后面就必须满足这个条件)。
  • A 1 ≤ A 2 A_1\le A_2 A1A2(小心不要忘了这个条件)。
  • 有且只有一个峰。
  • 有且只有一个谷。

现在有个长度为 N N N 的序列 P P P,求有多少个连续的子段是波浪序列。

思路

我们看一下条件——有且只有一个峰、一个谷。但是,整个序列里面会有许多峰、许多谷。然后,我们会从中选取一个峰、一个谷和一些其他类别的元素构成波浪序列。显然,我们要记下所有峰、所有谷的位置。默认按从小到大顺序记。

接下来,我们枚举选取子段的右端点,从第一个既包含峰又包含谷的位置开始,一直枚举到 N N N。考虑左端点可能的取值范围。前面通过从小到大的顺序暗示了这里的重要算法——二分。二分什么呢?左端点下边界?上边界?都可以。因为它是上下边界都与峰谷的位置有关,而确定上边界的峰一定“紧挨着”确定下边界的峰(指的是中间不会有别的峰),谷也是同理。式子自己想想吧!不会可以看代码。

代码

请点击 这里 查看 AC 记录。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;int n, p[300010];
int c1, v1[300010]; // peak
int c2, v2[300010]; // valley
int s1[300010];
int s2[300010];int main()
{cin >> n;for (int i = 1; i <= n; i++)cin >> p[i];for (int i = 2; i < n; i++){s1[i] = s1[i - 1];if (p[i - 1] < p[i] && p[i] > p[i + 1])v1[++c1] = i, s1[i]++;s2[i] = s2[i - 1];if (p[i - 1] > p[i] && p[i] < p[i + 1])v2[++c2] = i, s2[i]++;}if (!c1 || !c2){cout << "0" << endl;return 0;}long long ans = 0;for (int i = max(v1[1], v2[1]) + 1; i <= n; i++){int p1 = lower_bound(v1 + 1, v1 + c1 + 1, i) - v1 - 1;int p2 = lower_bound(v2 + 1, v2 + c2 + 1, i) - v2 - 1;
//		if (p1 < 0 || p2 < 0) p1 = p2 = 0;
//		cout << i << " " << p1 << " " << p2 << ": " << endl;
//		cout << " - " << v1[p1] << " " << v2[p2] << endl;
//		cout << " - " << v1[p1 - 1] << " " << v2[p2 - 1] << endl;if (v1[p1] > v2[p2]) continue;int vmx = max(v1[p1 - 1], v2[p2 - 1]) - 1;int vmn = min(v1[p1], v2[p2]) - 1;vmx = max(vmx, 0);if (i - vmx < 4) continue;if (i - vmn + 1 < 4) vmn = i - 3;ans += vmn - vmx;
//		cout << i << " " << vmx << " " << vmn << endl;}cout << ans << endl;return 0;
}

总结

时间复杂度 O ( N ⋅ log ⁡ N ) O(N\cdot\log N) O(NlogN),二分很好用。

http://www.lryc.cn/news/2378511.html

相关文章:

  • Spark,连接MySQL数据库,添加数据,读取数据
  • Linux容器技术详解
  • 【EDA软件】【联合Modelsim仿真使用方法】
  • STM32 __main
  • 【离散化 线段树】P3740 [HAOI2014] 贴海报|普及+
  • Python训练营打卡Day28
  • MODBUS RTU通信协议详解与调试指南
  • CSP 2024 提高级第一轮(CSP-S 2024)单选题解析
  • 六、绘制图片
  • Java 面向对象详解和JVM底层内存分析
  • 深度学习---知识蒸馏(Knowledge Distillation, KD)
  • 基于CNN卷积神经网络的带频偏QPSK调制信号检测识别算法matlab仿真
  • 【DAY21】 常见的降维算法
  • PostGIS实现栅格数据入库-raster2pgsql
  • 校园社区小程序源码解析
  • 第6章:文件权限
  • 使用 Python 连接 Oracle 23ai 数据库完整指南
  • C语言| 指针变量的定义
  • HTML 中的 input 标签详解
  • Python 在自动驾驶数据标签中的应用:如何让 AI 读懂道路?
  • 微信小程序之按钮短时间内被多次点击问题
  • 动态规划(3)学习方法论:构建思维模型
  • 两个电机由同一个控制器控制,其中一个电机发生堵转时,另一个电机的电流会变大,是发生了倒灌现象吗?电流倒灌产生的机理是什么?
  • Java 方法向 Redis 里操作字符串有什么需要注意的?​
  • ECMAScript 2018(ES2018):异步编程与正则表达式的深度进化
  • IntelliJ IDEA给Controller、Service、Mapper不同文件设置不同的文件头注释模板、Velocity模板引擎
  • 从零开始认识 Node.js:异步非阻塞的魅力
  • 【C语言练习】046. 编写插入排序算法
  • 【论文阅读】BEVFormer
  • IDEA编辑器设置的导出导入