【题解】codeforces765F Souvenirs

博客详细解析了如何利用线段树处理codeforces765F Souvenirs问题中的区间查询,通过离线处理和优化算法,将时间复杂度降低到O(lgn)。文章介绍了线段树的构造和查询方法,以及如何确定每次插入元素以最大化查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意:给定一个长度为n的数组与m个查询。第i个查询要求输出数组下标区间[li,ri]内的数之间的距离(差的绝对值)的最小值。

分析:离线处理查询。将查询区间按右端点从小到大排序,维护一个数据结构,使得将数组元素a1,a2,...,ai插入到数据结构之后能够快速查询以ai为右端点的查询区间的答案。考虑ai对查询区间的贡献,设d=|ai-aj|(j<i),则对于满足l≤j,r=a[i]的查询区间[l,r],有查询区间[l,r]的答案≤d。因此可以用线段树来维护答案,线段树每个结点记录左端点处于对应范围内时(当右端点 为ai时)的查询区间的上确界。

        若暴力处理ai对查询区间的贡献,则时间复杂度为O(n),这显然是不可接受的。不妨先设a1,a2,...,ai-1均大于等于ai(一般情况下处理2次即可),则在计算完元素对(ai,ai-1)对查询区间的贡献后,设下一个选取的元素对为(ai,aj),则aj应满足aj≤(ai+ai-1)/2。这是因为:1.aj≥ai-1时元素对(ai,aj)不优于元素对(ai,ai-1)的贡献;2.(ai+ai-1)/2≤aj≤ai-1时元素对(ai,aj)的贡献不优于元素对(ai-1,aj)的贡献。依次类推,计算ai对查询区间的贡献时间复杂度可以优化到O(lgn)。

        下面讨论程序的实现。我们需要一个数据结构,使得能够快速求出数组下标在[1,j-1]范围内大小在范围[ai,(ai+aj)/2]内的下标最大的数。可以建一棵线段树,线段树的每个结点[l,r]存一个vector,vector里将al,al+1,...,ar按从小到大排序,然后就可以O(lgn^2)地完成这件事(官方题解似乎有O(lgn)的做法)。

代码:

#inclu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值