• 2020.11.03提高组模拟


    GMOJ 2020.11.03【NOIP提高A组】模拟

    T1.6847通往强者之路

    (f_i) 表示走到第 (i) 块格时 (i) 上有多少砖,当 (i geq n) 时,(f_i = sum[j < i, j + f_j geq i])

    可以通过归纳证明得出:由(f_i = sum[j < i, j + f_j geq i])(f_j in ext{{n - 1, n, n + 1}})(f_i = n - 1 + [f_{i - n} geq n] + [f_{i - n - 1} geq n + 1]),所以 (f_i in ext{{n - 1, n, n + 1}})

    所以将 ( ext{{n - 1, n, n + 1}}) 表示为 ( ext{{0, 1, 2}}),则 (f_i = [f_{i - n} geq 1] + [f_{i - n - 1} = 2])

    (f_0) 开始以 (n) 个为一行将 (f) 排成一个方阵,设为 (g_{i, j}, j in [0, n - 1]),同上可得 (g_{i, j} = [g_{i - 1, j} geq 1] + [g_{i - 1, j - 1} = 2]),注意若 (j = 0) 时,(+) 后应为 ([g_{i - 2, n - 1} = 2])

    将其视作一种传递关系,则 (1) 的传递为 ((i, j) ightarrow (i + 1, j)),对于 (f) 来说,其实就是 (f_i ightarrow f_{i + n})

    (2) 的传递为 ((i, j) ightarrow (i + 1, j + 1)),注意当遇到 (0) 时,(2) 会将改为变为 (1) 并且消失,

    但是特殊的,((i, n - 1) ightarrow (i + 2, 0)),所以为了方便处理 (2),假想在方阵后加一列虚拟的 (j = n)(f) 也要相应的填入这一列),这样 (2) 的转移就是 ((i, j) ightarrow (i + 1, ext{(j + 1) % (n + 1)}))。对于 (f) 来说,也就是 (f_i ightarrow f_{i + n + 1})

    那么便很好做了,首先可以预处理出每个 (0) 变为 (1) 的行数(可能永远为 (0)),以及每个 (2) 消失的行数(也可能永远为 (2)),两者是一一对应的,用栈来模拟即可,时间复杂度 (O(n)),需注意 (2) 的转移可能一次跳跃两行。

    对于每个询问 (x),首先逆推回其在方阵起始行对应的位置 ((0, ext{x % n}))(也就是对应的 (f_{0..n - 1})),如果为 (0) 且该位变为 (1) 的行数大于 (x) 所在行数,那么 (f_x = 0),否则我们还需要判断是否有 (2) 刚好走到 (x) 所在方阵位置,同样逆推回起始行 ((0, ext{x % (n + 1)})),如若 (f_{ ext{x % (n + 1)}} = 2) 且消失的行数大于 (x) 所在行,那么 (f_x = 2)

    PS:包含大量 (f)(g) 之间的交互,慎读!写了 (1h) 多还是只能写成这鬼东西,必须差评!


    T2.6848融入社会的计划

    相比 (T1)(T2) 就清真多了,但考场还是没做出来.....(可是 (T2) 数据被贪心碾过去了?!)

    考虑 (dp),设 (f_{i, j}) 表示将 (a_i) 变为 (j)( ext{1 ~ i}) 满足条件的最小花费,转移很简单 (f_{i, j} = sum{f_{i - 1, k} + (j - a_i) ext{ , } [L leq j + k leq R]})

    显然,对于 (f_i) 而言,合法的 (j) 是一段连续的区间。

    并且可以得出,(f_{i, j}) 在合法区间内单调不减,并且(0 leq f_{i, j + 1} - f_{i, j} leq 1),可以归纳证明:

    首先将转移分为两部分:(f_{i, j} ightarrow f_{i + 1, k} ext{ , } ext{ } f_{i + 1,k} + (k - a_{i + 1}) ightarrow f_{i + 1, j})

    对于第一部分 (f_{i, j}) 会转移到 (f_{i + 1, k} ext{, } k in ext{[L - j, R - j]})(j) 增大的同时区间会相应地向左移,并且 (f_{i, j}) 不减,所以 (f_{i + 1}) 单调不升,并且 (0 leq f_{i + 1, j} - f_{i + 1, j + 1} leq 1)

    移项得 (f_{i + 1, j + 1} leq f_{i + 1, j} leq f_{i + 1, j + 1} + 1),再加 (j - a_{i + 1})((f_{i + 1, j + 1} + j + 1 - a_{i + 1}) - 1 leq f_{i + 1, j} + j - a_{i + 1} leq f_{i + 1, j + 1} + j + 1 - a_{i + 1})

    也就是 (0 leq f_{i + 1, j + 1} - f_{i + 1, j} leq 1),得证。

    (l_i, r_i) 表示 (f_i) 的合法区间,那么最后答案就是 (f_{n, l_n})

    然后就可以从 (n) 逆推答案了,首先求出 (l_i, r_i) 后,(a'_{i} = max(L - a'_{i + 1}, l_{i})),时间复杂度 (O(n))

  • 相关阅读:
    20155306 2016-2017-2 《Java程序设计》第1周学习总结
    20155213 2016-2017-2 《Java程序设计》第一周学习总结
    小议linux
    C语言学习的记忆
    我所期望的师生关系
    《暗时间》读书笔记(二)
    python——动态类型简介
    《Python学习手册》(二)
    python之模块导入和重载
    《暗时间》读书笔记(一)
  • 原文地址:https://www.cnblogs.com/zhouzj2004/p/13924728.html
Copyright © 2020-2023  润新知