【CSP试题回顾】202203-2-出行计划

文章讲述了如何利用前缀和数组和差分数组技巧解决CSP中的出行计划查询问题,通过高效地更新和查询时间区间,实现O(n+m)的时间复杂度。
摘要由CSDN通过智能技术生成

CSP-202203-2-出行计划

关键点:前缀和数组(高频考点)

详见:【CSP考点回顾】前缀和数组

解题思路

解法利用差分数组技巧,使得更新时间区间的操作和查询操作的时间复杂度都是 O(1),整体算法的时间复杂度主要由遍历出行计划和查询决定,即 O(n + m)。

  1. 初始化一个数组 diffArr 用于记录时间点的变化,这个数组的大小设定为能包含所有可能的时间点(根据问题限制,时间点不会超过 200,005)。

  2. 遍历所有 n 个出行计划,对于每个计划,计算出它有效的时间区间 [x, y],即从 ti - k - ci + 1 到 ti - k。如果计算出的 y < 1,则忽略该出行计划,因为它不可能在任何查询时间内有效。

  3. (重点) 使用差分数组的技巧来处理时间区间的更新。如果一个出行计划在时间区间 [x, y] 内有效,那么在 diffArr 数组中,位置 x 的值增加 1(表示从时间 x 开始,出行计划数增加),而位置 y+1 的值减少 1(表示从时间 y+1 开始,出行计划数减少)。这是因为在差分数组中,一个区间的开始位置加 1,结束位置的下一个减 1,可以用来反映这一区间内的数量变化。

  4. 在更新完所有出行计划后,遍历 diffArr 数组计算其前缀和,这将转换 diffArr 数组成为一个在每个时间点具体有多少出行计划活跃的数组。

  5. 对于每个查询时间 q,直接输出 diffArr[q] 的值,这就是在时间点 q 活跃的出行计划总数。

完整代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n, m, k, ti, ci, q, diffArr[200005];

int main() {
	cin >> n >> m >> k;

	for (int i = 0; i < n; i++)
	{
		cin >> ti >> ci;
		int x = ti - k - ci + 1, y = ti - k; // 符合条件的时间区间 [x, y]

		if (y < 1) continue; // y < 1直接跳过(肯定没有任何一个出行符合条件)
		else
		{
			x = max(1, x); // x至少为1(规定从1开始)
			diffArr[y + 1]--, diffArr[x]++; // 在x处加1,y+1处减1,用差分数组记录每个时间点的变化			
		}
	}

	for (int i = 1; i < 200005; i++)
	{
		diffArr[i] += diffArr[i - 1]; // 差分数组计算前缀和
	}

	for (int i = 0; i < m; i++) // 处理查询
	{
		cin >> q;
		cout << diffArr[q] << endl; // 满足条件的出行计划总数
	}

	return 0;
}

请添加图片描述

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值