2020ICPC(小米邀请赛1) - Phone Network(线段树优化,难题)

题目链接

题目大意:

一个长度n的数组,每个数在[ 1,m ]区间内,保证了每个数(在[ 1 , m ])至少出现过一次。对于每个 i ∈ [ 1 , m ],分别输出在原数列中,包含了 [ 1 , i ] 的所有种类数字的最短区间长度。

这里官方题解给出了一种全新的思路。

在这里插入图片描述

就如同做dp题,迟迟找不到dp数组含义应该定义为什么,我也未曾设想这个数组。

题解还有每次更新后,答案的变化没提,少了一个关键步骤,下面我来解析一下。

设当前要计算[1,x]
令r[i]为以i为左端点,包含[1,x]的最小右端点
如果不存在满足条件的右端点则设r[i]为inf.

推断一:r[i]数组是单调不递减的
推断二:对遍历i∈[1,n]遍历r[i]-i+1,取min就是当前答案

用计算[1,x]后的r[i]数组推断[1,x+1]的r[i]数组

设(x+1)的在原数组的位置为p(1),p(2),p(3)...p(t),(假设出现了t次)
对于k∈[p(i-1)+1,p(i)],r[k]如何调整
如果r[k]<p(i),表示x+1未被包含在这个区间,所以右端点要移到p(i),即r[k]=p(i)
相反r[k]>=p(i),表示x+1已经包含在这个区间,所以不变。
总之 r[k]=max(r[k],p(i));

但是一个个修改复杂度较高,而且这是典型的区间修改(根据推断一)
线段树毕竟是优化工具,下面依旧用线性分析

对于k∈[p(i-1)+1,p(i)],r[k]的变化
1、先找到区间内小于p(i)的最大位置
2、之前的r[k]全改为p(i)
3、最后一个位置[p(t)+1,n],因为不成立,全设为inf

对于k∈[p(i-1)+1,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值