zoukankan      html  css  js  c++  java
  • 星际穿越

    这道题忘记了,再推一遍。
    引理1:我们最多只会向右跳一次,且向右跳操作一定在开始。
    考虑从(x_i)右边跳到左边的起始点(z)。如果我们经过了若干个点({b}),则由于(z)能跳到(<x_i)的点,所以能跳到(x_i)
    显然我们不用跳(b),直接从(s)跳到(z)即可。
    如果我们在(x_i)左边跨过(x_i)跳到右边的点(a),则显然一开始能从(s)跳到(a),矛盾。
    假设我们在第一次从右边跨过左边(或没有跨过左边)然后向左跳。
    如果我们在这个过程中向右跳,假设跳到点(d),我们第一次跳后(包含第一次)跳过的点序列为({c})
    则找到(c)中第一个大于(d)的元素(e),则从(e)开始跳到(d)最优。
    考虑bfs,每次求出距离当前点(leq d)的区域。
    引理2:当(d>1)时区域是一个区间。
    如果我们右跳后跳到节点的区间不能够覆盖(x_i),则显然还要右跳,矛盾。
    考虑归纳。假设我们(leq x_i)的区间为([l,x_i])
    (d>1)时,(x_i)右边能跳到节点肯定能覆盖(x_i)且是一个区间。
    ([l,x_i])假若区间最小(l)值为(v),则我们下一步显然能够跳到([v,x_i])
    考虑求出(d)增加(1)每一轮有多少节点不能到达。
    假设我们区间覆盖(l_i)需要用(d1)步。
    设一数列({x})({x_j})表示(d=j)时覆盖区间右端点。
    我们需要求出(sum_{i=2}^{d1}x_i-(l_i-1)*d1)
    (d1)可以倍增。可以维护倍增时区间最小值。
    (x)的和也可以用倍增维护。
    还要预处理出后缀(l)最小值。
    以上信息都可以在最多(O(nlog_2n))时间内维护。

  • 相关阅读:
    Oracle的数据伪列(ROWNUM)
    数据库的多表查询(详细案例分析)
    计算1至n的k次方的和
    位数对调(代码重构)
    java实现汉诺塔算法
    线程与进程详解
    java中properties的使用实例
    java中同步(synchronized)详解
    文件的拷贝操作
    文件的读取操作
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14359379.html
Copyright © 2011-2022 走看看