几道线段树题

学习了几天线段树,做了几道线段树题,挺有成就感的\(^o^)/~


 

POJ2528 Mayor's posters

    线段树入门题。题目抽像出来就是:给你一根长为L(L = 10000000)的数轴,然后给出N(N <= 10000)组区间[Li, Ri]将数轴对应部分染颜色i,后面染的颜色的会把前面的给覆盖掉。最后要求出数轴上总共有多少种颜色。由于数轴很长,直接建线段树肯定会超时,而N很小,所以考虑离散化。比如给出的区间是:[1, 4]、[4, 1000000],我们把端点去重后排序:1、4、1000000,然后给定离散化值:1、2、3。然后区间就变成[1, 2]、[2, 3]了,变小了,所以肯定就不会超时啦!但Discuss里有大牛说这样离散化是有问题的,比如给出几个区间:[1, 10]、[1, 2]、[7, 10],去重排序:1、2、7、10,离散化:1、2、3、4,则区间变为[1, 4]、[1, 2]、[3, 4]。看,问题来了吧?这样做我们的结果是2(种不同颜色),而实际结果是3(种不同颜色)。原因就是3~6这一段被我们消掉了!注意一下排序过程:1、2、7、10,显然2和7之间的东西会没的。所以我们重新用一种离散化方式,当排序后相邻点距离大于1,则离散量+2,否则+1。于是离散化后变成:1、2、4、6,即区间变为[1, 6]、[1, 2]、[4, 6],得到的结果仍然是3。

    然后不知道是哪位大牛的解题报告说要把区间倒着插入,这样有一个好处是不需要考虑覆盖问题。但我超时了好多次啊!后来参考他的牛码,发现他竟然也是正着插入的,我狂晕!然后我改为正着插入就很快AC了,高兴啊!





POJ2828 Buy Tickets

    这道题还是蛮有意思的(恩,题目很有意思),讲的是插队的过程。售票员的位置是0,然后有N个人,每个人都插队,第i个人可以插他前面0~i-1个人的队,即跑到那个人后面。要求出最终队列。解释一下样例:

4    //4个人
0 77  //第1个人(他/她的编号是77)插第0个人的位置
1 51  //第2个人(他/她的编号是51)插第1个人的位置
1 33  //第3个人(他/她的编号是33)插第1个人的位置
2 69  //第4个人(他/她的编号是69)插第2个人的位置
有图有真相哦(*^__^*) 嘻嘻……

最终队列就是77 33 69 51。

做法是倒着插,因为最后一个人的位置一定是确定的,所以我们可以确定最后一个人的位置(木有错吧?)。然后,剩下的人也以同样的方式,插第k个人的位置表示前面有k个空格。比如上面的例子,先确定最后一个人的位置:[空, 空, 69, 空]。然后剩下三个人的位置肯定在空的位置处(并且他们是连在一起的,因为队伍肯定是连续的嘛),我们在插第三个人(1, 33)的时候,可以想像前两个人已经存在了,但不知道他们的位置在哪里,不管,反正它们是连续的(肯定是第一和第二个空),我只要前面有1个人(空格),然后插入即可(此时第二个人会被移到第四个格,不管它,想像而已,嘻嘻),然后变成[空, 33, 69, 空]。然后就照这样下去插就完成了。线段树的结点存放这一段里面有多少个空格,然后就可以很快地确定要插入的位置了,好棒啊!





POJ2777 Count Color

    同第一题类似,抽象出来就是:给一根长度为L(L <= 100000)的数轴,一开始数轴上都是颜色1。然后给出O个操作,两种形式,一种是C L R COL,表示把数轴[L, R]这一段染成颜色COL(COL <= 30);另一种形式是P L R,表示询问[L, R]这一段上有多少种不同的颜色。

    这题比较好的地方就是不用离散化,然后由于颜色数很少,可以用位来表示。结点存放颜色信息,比如这一段上有颜色1, 4, 7,就用一个32位数表示001001001。而两段上面的颜色就是这个信息的一个或。






POJ2750 Potted Flower

    变态题啊!给一个有N个结点的环,每个结点上各一个可正可负可零的数值。现要取连续k个结点(1 <= k <= N - 1)的一段,使这一段的和最大。并且会经常出现修改某个结点的值的情况发生的,每修改一次就要输出一个最大的和。

    把环拆成链1, 2, ..., N,一开始以为,只要找出链中和最小的那一段,然后用总和减去那一段就是最大和,可后来发现错了。比如要取的这一段是在中间:ABBBBBA,那么这种假设就不成立了。想一想所有可能出现的情况:一种是该链中某段得到最大和,另一种是链的前一部分和后一部分连起来构成最大和。对于后一种情况,其实就造价于找出链的最小和,用总和去减。所以,我的线段树一定要存储该段内的连续最大和与连续最小和,然后取这两种情况的最大值即是题目要求。为了得到最大和与最小和,结点存放的信息有:该段区间总和Sum、区间最大和VMax,区间最小和VMin,区间左端点开始连续的一段的最大和值LMax与最小和值LMin, 区间右端点开始连续的一段的最大和值RMax与最小和值RMin。然后以最大值为例有:

Sum[I] = Sum[L] + Sum[R]

LMax[I] = max(LMax[L], Sum[L] + LMax[R])

RMax[I] = max(RMax[R], Sum[R] + RMax[L])

VMax[I] = max(VMax[L], VMax[R], RMax[L] + LMax[R])

然后,由于不能取走N个点,需要加个判断:如果全总为正数(因为只有这种情况才会取走N个点),就用总和减去最小段和。否则,就取max(VMax, Sum - VMin)。

转载于:https://www.cnblogs.com/comeon4mydream/archive/2011/07/29/2121399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值