第36次ccfcsp认证第二题
时间: 2025-03-29 20:01:34 浏览: 148
### 关于CCF CSP认证第36次考试第二题的内容
题目描述如下:
#### 梦境巡查
给定一个长度为 $N$ 的整数数组 $A$ 和一个正整数 $K$,定义一种操作:对于任意区间 $[L,R]$ ($1 \leq L \leq R \leq N$),如果该区间的子数组满足条件 $\text{max}(A[L..R]) - \text{min}(A[L..R]) \leq K$,则可以对该区间执行一次“梦境巡查”。
目标是计算能够执行“梦境巡查”的不同区间数量。
输入格式:
- 第一行包含两个整数 $N$ 和 $K$;
- 第二行包含 $N$ 个整数表示数组 $A$。
输出格式:
- 输出一个整数,表示符合条件的不同区间数量。
数据范围:
- 对于 $50\%$ 的数据,$1 \leq N \leq 10^3$
- 对于 $100\%$ 的数据,$1 \leq N \leq 10^5$, $|A[i]| \leq 10^9$
---
#### 解法思路
此问题可以通过滑动窗口结合单调队列的方法解决。具体实现过程如下:
1. 使用双端队列分别维护当前窗口的最大值和最小值。
2. 利用滑动窗口的思想逐步扩展右边界,并动态调整左边界以保持最大值与最小值之差不超过 $K$。
3. 统计所有合法的区间数目。
以下是基于上述方法的具体代码实现[^1]:
```python
from collections import deque
def count_valid_intervals(n, k, a):
max_deque = deque() # 单调递减队列,用于存储可能的最大值索引
min_deque = deque() # 单调递增队列,用于存储可能的最小值索引
left = 0
result = 0
for right in range(n):
while max_deque and a[max_deque[-1]] <= a[right]:
max_deque.pop()
max_deque.append(right)
while min_deque and a[min_deque[-1]] >= a[right]:
min_deque.pop()
min_deque.append(right)
# 调整左侧指针使得窗口内的最大值与最小值之差小于等于k
while max_deque and min_deque and (a[max_deque[0]] - a[min_deque[0]]) > k:
if max_deque[0] < min_deque[0]:
left = max_deque.popleft() + 1
else:
left = min_deque.popleft() + 1
# 计算以right为右侧边界的合法区间数量
result += right - left + 1
return result
# 输入处理部分
n, k = map(int, input().split())
a = list(map(int, input().split()))
print(count_valid_intervals(n, k, a))
```
---
#### 复杂度分析
- 时间复杂度:由于每个元素最多被加入和移除队列各一次,因此整体时间复杂度为 $O(N)$。
- 空间复杂度:需要额外的空间来保存两个单调队列,空间复杂度为 $O(N)$。
通过这种方法可以在合理的时间范围内完成大规模的数据测试案例。
---
阅读全文
相关推荐


















