zoukankan      html  css  js  c++  java
  • 联合省选 2021 B 卷题解

    Day1

    数对

    给定 (n) 个正整数 (a_i),请你求出有多少个数对 ((i, j)) 满足 (1 le i le n)(1 le j le n)(i e j)(a_i)(a_j) 的倍数。

    (2 le n le 2 imes 10^5)(1 le a_i le 5 imes 10^5)

    考虑使用桶,记 (cnt_x) 表示 (a_i = x) 的个数。

    那么分两种情况讨论,第一种情况是 (a_i = a_j = x),对答案的贡献为 (sum inom{cnt_x}{2});第二种是 (a_i = x < a_j = y),那么这时候枚举 (a_i) 的值 (x),同时枚举 (x) 的倍数 (y),对答案的贡献为 (sumlimits_{x} sumlimits_{y} cnt_x cnt_y)

    时间复杂度是经典的调和级数 (O(frac{n}{1} + frac{n}{2} + frac{n}{3} + cdots) = O(n ln n))

    卡牌游戏

    (n) 张卡牌,第 (i) 张卡牌的正面有数字 (a_i),背面有数字 (b_i),初始时所有卡牌正面朝上。

    现在可以将不超过 (m) 张卡牌翻面,最小化朝上的 (n) 个数字的极差。

    (3 le n le 10^6)(1 le m < n)(1 le a_i, b_i le 10^9)(a_i) 单调不下降,(2n) 个数字互不相同。

    先把 (a, b) 拼成一个长度为 (2n) 的数组 (c) 排序。

    对于这个有序的数组,极差即是选中的那一段 (l, r)(c_r-c_l)

    于是用双指针枚举 (l, r),不在 (l, r) 当中则意味着那一位被删除,具体要求是:

    • 删掉的 (a) 面不超过 (m)
    • 不存在同一张卡牌的 (a, b) 面同时被删除。

    对于第一条开一个 (cnt) 维护,第二条开一个 (vis) 数组维护即可。

    时间复杂度 (O(n log n)),不明白 (a) 有序有什么意义。

    图函数

    对于一张 (n) 个点 (m) 条边的有向图 (G),定义函数 (f(u, G))

    • 初始化返回值 (cnt = 0),图 (G' = G)
    • (1)(n) 按顺序枚举顶点 (v),如果当前的图 (G') 中,从 (u)(v) 与从 (v)(u) 的路径都存在,则将 (cnt + 1),并在图 (G') 中删去顶点 (v) 以及与它相关的边。
    • (2) 步结束后,返回值 (cnt) 即为函数值。

    现在给定一张有向图 (G),请你求出 (h(G) = f(1, G) + f(2, G) + cdots + f(n, G)) 的值。

    更进一步地,记删除(按输入顺序给出的)第 (1)(i) 条边后的图为 (G_i),请你求出所有 (h(G_i)) 的值。

    (2 le n le 10^3)(1 le m le 2 imes 10^5)(1 le x_i, y_i le n),没有重边和自环。

    因为只要求求出每个 (h(G_i)),而不是求具体的 (f(u, G_i)),所以考虑贡献法。

    考虑一对 ((u, v)) 如果能对 (f(u, G_i)) 造成贡献,当且仅当存在一条 (u o v o u) 的环,且这个环上没有编号 (<v) 的点。

    于是问题转化为对于 (forall G_i),求 (G_i) 中有多少 ((u, v))(u ge v))满足存在 (u o v o u) 的环不经过编号 (< v) 的点。

    一个点对显然会对一个 (G) 的前缀造成贡献,令 (path(u, v)) 表示最大化的 (u o v) 的路径上经过的边的编号的最小值。那么 (G_{1 sim min(path(u, v), path(v, u))}) 会得到贡献。

    可以直接 Floyd (O(n^3 + m)) 或 Dijkstra (O(nm log m)) 求出。

    当然这不稳,可以考虑一个更高明的做法。枚举 (v),在每张图中只保留 ([v, n]) 那些点,求出每张图中它能到达的点的个数即可。

    当然直接这样模拟是 (O(nm^2)) 的,考虑反转时间轴变成逆序加边,对于一条新加的边 ((a, b))(a, b ge v)):

    • 如果 (vis_a = 1)(vis_b = 0),那么从 (b) 开始 BFS;
    • 如果 (vis_a = 0)(vis_b = 0),那么先加到图中,等着以后可能有用;
    • 否则这条边没有意义。

    易证每一条边最多只会用到一次,所以在 BFS 的时候“过河拆桥”即可。时间复杂度 (O(nm))

    Day2

    取模

    给定 (n) 个正整数 (a_i) 请你在其中选出三个数 (i, j, k)(i e j)(i e k)(j e k)),使得 ((a_i + a_j) mod a_k) 的值最大。

    (3 le n le 2 imes 10^5)(1 le a_i le 10^8)

    首先将 (a) 数组排序,逆序枚举 (a_k),在前面做二分或者双指针求出 ((a_i + a_j) mod a_k) 的最大值更新答案。

    (ans ge a_k) 的时候就可以 break 了,可以证明枚举的 (a_k) 的个数是 (log) 级别的,但我不会证

    宝石

    给定一棵大小为 (n) 的树以及 (m) 种宝石,结点 (i) 上有第 (w_i) 种宝石。

    宝石收集顺序是一个长度为 (c) 的序列 (P)(P) 中没有重复元素。

    (q) 次询问,每次给出 (s, t),问从 (s) 走到 (t) 的过程中,所经过的结点的 (w) 形成的序列与 (P) 的最长公共子序列的长度。

    (1 le n, q le 2 imes 10^5)(1 le c, m le 5 imes 10^4)(1 le P_i, w_i le m)

    (s o t) 拆为 (s o ext{lca}, ext{lca} o t) 的两个过程。

    考虑链上的情况,记结点 (u) 的后继 (suc_{u}) 为其右边最近的满足 (w_v)(P) 序列中恰好是 (w_u) 的下一项的 (v)

    那么如果询问的 (s < t),就从 (s) 右边的第一个 (w = P_1) 的位置开始,不断跳 (suc),直到越过 (t) 结束,跳的次数就是询问的答案。不难发现这个过程可以倍增优化。

    现在搬到树上,(s o ext{lca}) 的过程不难套用上述方法,但如果考虑 ( ext{lca} o t) 呢?

    一个解决办法是把过程拟过来,记录 (pre_{u}) 为其父亲链上的最近的满足 (w_v)(P) 序列中恰好是 (w_u) 的前一项的 (v)

    每次询问的时候二分答案 (a),从 (t) 上方的最近的 (w = P_a) 的那一个位置开始不断跳 (pre) 就行了。

    至于找到“(t) 上方的最近的 (w = P_x) 的位置”,可以使用可持久化线段树维护这个东西。

    时间复杂度 (O(q log^2 m))

    滚榜

    给定一个长度为 (n) 的数组 (a),求有多少 (1 sim n) 的排列 (p),满足存在一个 (sum b = m) 的不下降序列 (b),使得对于任意 (i, j)(i < j)),都有:

    • (a_{p_j} + b_{p_j} ge a_{p_i} + b_{p_i} + [p_i < p_j])
    • (a_{p_i} + b_{p_i} ge a_{p_j} + [p_j < p_i])

    (1 le n le 13)(1 le m le 500)(0 le a_i le 10^4)

    容易发现 (b) 的分配是贪心的,每次给出最小的 (b),只要 (sum b le m) 就是合法的方案。

    一个显然的结论是“当前选手想当 rank 1 只要比上一名选手高即可”,这是因为上一名选手是当前的 rank 1。

    于是可得(忽略编号问题,这个显然是容易处理的):

    • 如果 (a_i ge a_{i - 1}),则 (b_i = b_{i - 1})
    • 如果 (a_i < a_{i - 1}),则 (b_i = b_{i - 1} + a_i - a_{i - 1})

    综合一下上面两个式子其实就是 (b_{i} = b_{i - 1} + max(0, a_i - a_{i - 1}))

    进而通过考虑贡献可以知道 (sum b = sum max(0, a_i - a_{i - 1}) (n - i + 1))(每个贡献都是一个后缀)。

    于是考虑状压 DP,用 (f(S, i, j)) 表示,当前使用过的集合是 (S),最后一个选的是 (i),以及当前对 (sum b) 的贡献是 (j)。转移的时候枚举接下来选哪一个人,计算一下贡献即可。

    时间复杂度 (O(2^n n^2 m)),轻微卡常。

  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/syksykCCC/p/AHOI2021.html
Copyright © 2011-2022 走看看