zoukankan      html  css  js  c++  java
  • COCI 2015/2016 Day 8 PROKLETNIK

    PROKLETNIK

    题目描述:给出(n)个数,定义一段连续的数为魔法串是该区间的左右端点值正好是区间的最小值与最大值(最小值可以在左也可以在右,最大值也一样)。(Q)个询问,每次询问一个区间([L, R]),问该区间的子区间为魔法串的最大长度。

    solution
    离线所有的询问,现在考虑左小右大的魔法串。然后如果可以维护(i)之前的点为左端点的最长魔法串的答案,那么以(i)为右端点的询问的答案就是([L, R])取最大值。
    问题是如何维护。
    因为现在只考虑左小右大的魔法串,所以考虑维护一个单调递增的队列,先考虑(i)入队
    1、(i)不小于队尾。设(taller[i])表示前(i)个数比(i)大的,且离(i)最近的位置,那么队列中在(taller[i])右边的点都可以以(i)为右端点,而且(i)是当前它们的最优解。(下一个点会解释为什么只有队列中的点才能被更新答案)可以考虑用线段树来维护这个队列中的点的最优解,线段树对应队列的第几个数(即对应队列下标),(i)进队。
    2、(i)小于队尾。这时,队尾不可能再成为魔法串的左端点(因为(i)小于队尾,队尾不是最小值),也就是说队尾的答案不会也不能在更新,所以可以把队尾的答案取出,存进另一棵线段树(以队列中的值为下标,即原来数的下标)或树状数组。不断地把队尾取出,直到(i)不小于队尾。这时(i)不能更新队列中的任何一个数(因为(i)不是最大值),所以(i)直接进队。
    对于以(i)为右端点的询问,求出第二棵线段树([L, R])的最大值,以及(L)在队列中的位置(w),然后求队列的那棵线段树(w)之后的最大值,取这两个值的最大值就是答案。

    时间复杂度:(O((Q+n)logn))

  • 相关阅读:
    Java Static Import的用法
    Java EE官方文档汇总
    JDK/Java SE官方文档汇总
    IntelliJ IDEA删除所有断点
    Java基础教程:tutorialspoint-junit
    Spring MVC中@RequestParam/@RequestBody/@RequestHeader的用法收集(转)
    SpringBoot中@EnableAutoConfiguration注解用法收集
    Spring Cloud ZooKeeper集成Feign的坑3,程序Run模式运行没事,Debug模式下报错
    Java中HashMap的初始容量设置
    win7下scheme环境配置
  • 原文地址:https://www.cnblogs.com/GerynOhenz/p/5388591.html
Copyright © 2011-2022 走看看