• [Luogu]P5513 [CEOI2013]Board


    (Link)

    Description

    Solution

    首先根据手动模拟,可以发现对于两个节点(A,B),首先必须要花费一些代价向上跳到同一深度。

    然后再让(A,B)同时向上跳,中途可能(A,B)再通过只走横向的边相遇。这样就可以维护最小值,求出答案了。

    现在主要的问题就是要怎么写高精度。注意到我们需要维护一个初始值为(1)的数(x),并支持以下(3)种操作:

    (1.)乘以(2)(并加上(1));

    (2.)除以(2)并下取整;

    (3.)加减(1)

    所以可以用二进制高精,并将输入操作序列转化为只有向下移动的序列,这样就方便操作了。

    我们维护一个数组 (a_{1}, cdots, a_{n},) 表示当前数为 (sum_{i=1}^{n} a_{i} 2^{n-i})。((0)是向左,(1)是向右)加减(1)的操作直接做,乘以(2)(并加上(1))的操作就把(n)加上(1),并让(a_n=0/1),除以(2)的就先维护进/退位,再把(n)(1)即可。处理完后,再从后往前维护一遍进/退位。

    (处理进/退位:a[pos - 1] += ((a[pos] - (a[pos] & 1)) >> 1); a[pos] &= 1;

    但是这样做为什么是对的呢?

    注意到对(a)序列进行的操作,都唯一且恰好对应对数(x)(即当前节点编号)的操作。且因为我们维护了进位,所以通过(a)序列算出来的数值一定和(x)相等。从而这样是可以做的。

    于是先把输入的操作序列转化为两个序列(a,b),再维护一个(Delta)表示(A,B)(在同一层)的横向距离,手模可以发现(Delta = 2 * Delta + a[i] - b[i])。再通过之前说的方法,既可以求出答案。

    当然,如果计算过程中(Delta)的值过大,可以直接(break)掉(这时肯定不会是答案)。

    时间复杂度(O(n+|S|))

  • 相关阅读:
    Ajax基础1
    jQuery框架源码解读
    关于struts、spring 和 hibernate的说明
    struts2学习笔记(一)
    NodeJS+MongoDB
    最佳实践(二)
    ajax请求web容器控制超时
    实战经验
    javascript学习笔记(二)
    spring学习笔记(六)
  • 原文地址:https://www.cnblogs.com/andysj/p/13856791.html
Copyright © 2020-2023  润新知