zoukankan      html  css  js  c++  java
  • loj rounds 补题

    LibreOJ β Round

    ZQC 的树列

    考虑原序列中的所有子序列中,美观值最大的一定是原序列。
    那么这些子序列美观度与原序列相同的充要条件是包含每个最值点。
    由于我们要构造一个特征值为(k)的序列。其实只用(0, 1, 2)三种元素就能构造。构造的序列一定是一段0(,一段1),一段2(,一段1),一段0(,一段1)...
    考虑一段长度为(l)的连续1的贡献为(2 ^ l),一段长度为(l)的连续0或2的贡献为(2 ^ l - 1)。相当于把(k)分解成这种数的乘积。(只要分解出来,长度一定不会超过限制)
    这个东西其实有点困难。因为朴素的贪心分解(从大到小枚举因数)是错的,反例如(315 = 3 * 3 * 5 * 7 = 5 * 63 = 3 * 7 * 15)
    但是其实反例很少,因为这种情况只会出现在要分解的数能被(63)整除的情况下。把63屏蔽掉即可。
    为什么只有63被屏蔽呢?事实上因为它是满足((2 ^ k - 1) | prod_{i = 2} ^ {k - 1} (2 ^ i - 1))的,就会被叉。

    ZQC 的游戏

    把每个球(除了1号)和每个食物看做一个点,每个球与在其移动范围内的食物连一条容量为(w)的边(食物的重量),并且给每个球一个流量限制,使得其最终重量不能超过1号球,然后跑一个最大流,判断一下所有食物是否能把重量分光,即判断一下最大流是不是等于食物的总重量(预先把1号球能吃的都给1)即可。

    ZQC 的拼图

    二分是显然的。然后就是一个dp再优化一下了。(不优化竟然也能过!)

    ZQC 的手办

    这似乎是一个和超级钢琴一样的套路。用线段树+堆即可。
    线段树维护的数区间最小值即其位置(如果有多个最小值,取任意一个位置即可)。
    然后每次询问的话,考虑先找出整段区间的最小值及其位置,然后构成一个四元组((l, r, v, x)),考虑每次在堆中取出(v)最小的四元组,然后加入((l, x - 1, query(l, x - 1).v, query(l, x - 1).x))((x + 1, r, query(x + 1, r).v, query(x + 1, r).x))即可。复杂度(mathcal O(q {log_2} ^ 2 n))

    LibreOJ β Round #2

    模拟只会猜题意

    (mathcal O(n ^ 2))处理出每个区间的答案,它对一段前缀询问区间产生贡献(打个标记处理后缀max即可)。复杂度(mathcal O(n ^ 2 + q))

    贪心只能过样例

    bitset乱搞。复杂度(mathcal O(frac{n V ^ 4}{omega}))

    DP 一般看规律

    看上去就是一道启发式合并。每次合并用set合并,而答案显然是随操作单调的。
    合并的时候要更新答案,具体就是枚举小的set里面的元素,在大set里面查找前驱后继。
    注意如果没有颜色(x)的位置或没有颜色(y)的位置要直接对set赋值。(x = y)时要跳过。
    复杂度(mathcal O(q + n {log_2} ^ 2 n))
    然后注意set的赋值或赋值是(mathcal O(size))的,但是交换是(mathcal O(1))的,所以可行的时候用swap代替赋值。

    计算几何瞎暴力

    我眼中的神仙题。
    这个排序操作看起来很不好搞。
    但是有一种操作叫做维护两个数据结构,一个维护的是序列中排过序的部分,一个维护的是序列中未排过序的部分。
    考虑排过序的部分肯定是个前缀,未排过序的部分就是个后缀,可以直接用序列的前缀和维护未排过序的部分,用trie维护排过序的部分。
    考虑具体一点。
    假设现在没有全局异或操作。
    对于一次区间查询,显然数转化为前缀和来做,那么对于一次排序,就把序列中未排过序的部分加入trie中。
    考虑trie的有序性,所以在trie上询问就可以直接二分。具体来说,对于trie树上每个节点都要维护一下,其子树内,每个二进制位有多少个1,二分的时候,每次和子树的(sz)比一比。(有点抽象)
    如果有异或,这个东西会变得复杂一点。
    考虑一次异或对未排过序的部分的影响,显然是都有的,那我们不妨打个全局标记。
    对于trie树里面排过序的部分,我们维护两个全局标记,一个是当前所有异或标记的异或值(tag),一个是最后一次排序时的异或值(lazy)
    因为对于trie树来说,一次异或相当于交换某些子树,所以(lazy)就是用来做这个用的;而(tag)的话,就是询问的时候再用的。
    复杂度(mathcal O(q {log_2} ^ 2 V))

    LibreOJ β Round #3

    绯色 IOI(开端)

    这个东西其实结论还挺好猜的。把答案式中的平方拆掉,然后发现要最大化(sum_{i = 1} ^ n w_{i_1} w_{i_2})
    这其实和一个那啥不等式很像,反正大的和大的乘结果总要大一点。
    所以最后的最优匹配方案就是(n o n - 1)(i o i - 2)(3 leq i leq n)), (2 o 1)

    绯色 IOI(抵达)

    哎,还是小结论的问题。
    考虑对于一个点(i)和它的庇护点(p_i)(i)(p_i)一定构成了一个长度为2的环(即(p_{p_i} = i))。
    因为考虑(p)是一个排列,如果(p)中有长度大于2的循环(轮换),在树上一定无法表示(在图上也应形成一个环,但是图是树,没有环)。
    所以我们可以求出对于每个点,和哪个点匹配,这显然树可以(mathcal O(n))的。
    然后设一个点的度数为所有与这个点相邻的匹配的远端顶点个数(还未被访问过的),考虑做一个拓扑排序,每次把编号最小且度数为0的点取出即可。
    复杂度(mathcal O(n log n))

    LibreOJ β Round #4

    游戏

    一般情况下,能操作最后一步的人有决定胜负的权利。(特判一些情况)

    多项式

    应用扩展欧拉定理即可。

    [x ^ k - x ^ {k mod phi(m) + phi(m)} equiv 0 (mod m) ]

    子集

    由于奇偶性相同的数是必然可以直接放一起的,考虑把原数组按奇偶分成二分图。
    对于左右两边的点对,若满足((a_i, b_j) = 1)((a_i + 1, b_j + 1) = 1),连一条边;所求的就是最大独立集的大小。

    LibreOJ β Round #5

    自然语言

    如果存在两个连续的N,一定不合法(因为始终会存在两个连续的N),先判掉。
    否则,对于en,一定会把NVV..VVN变成NVN,如果串满足NVNV...VNVN...的形式,且至少存在一个N,则一定可行;
    对于zh,也一定会把NVV..VVN变成NVN,但由于没有N -> VN的方式,所以如果串满足NVNV...,且至少存在一个N,则一定可行。

    最小倍数

    暴力两只log加剪枝可过。

    LibreOJ β Round #6

    花煎

    花团

    题解

    花火

    题解

    Hello 2018(LibreOJ β Round #7)

    奴隶主的游戏

    猜结论,答案和(n)(k)的奇偶性有关((k)如果很大,结论会失效),主要基于存在对称性的方法。

    小埋与游乐场

    最优解下只会有两种情况给以配对:

    [lowbit(a_i) > lowbit(b_j) \ a_i = b_j \ ]

    则对于(lowbit)相同的点可以当成等价类。
    ({ca}_i)(a)中第(i)(lowbit)的数量,({cb}_i)(b)中第(i)(lowbit)的数量,({cc}_i)表示(a_j = b_k)(lowbit(a_j))是第(i)(lowbit)的最大匹配对数。
    则建图:

    [egin{aligned} & (A_i, B_j, infty, 2 ^ {i - 1} - 2 ^ {j - 1}) (i > j) \ & (A_i, B_i, {cc}_i, 2 ^ {i - 1}) \ & (S, A_i, {ca}_i, 0) \ & (B_i, T', {cb}_i, 0) \ & (T', T, k, 0) \ end{aligned} ]

    跑一个最大费用任意流即可。

    匹配字符串

    枚举上一个0出现的位置,有递推式

    [f_n = sum_{i leq m} f_{n - i} ]

    这是一个常系数线性齐次递推,可以做到(mathcal O(m ^ 3 log n))(mathcal O(m ^ 2 log n))(mathcal O(m log m log n))
    但是这显然过不去。
    (s_i = sum_{j = 1} ^ i f_j),则有(s_i - s_{i - 1} = s_{i - 1} - s_{i - 1 - m}),即(s_i = 2s_{i - 1} - s_{i - 1 - m})
    考虑建一张有向图,连边((i - 1, i, 2))((i - 1 - m, i, -1))。则(s_n)就是0号点到(n)号点的路径权值和,每条路径的权值等于路径上所有边权乘积。
    枚举经过了(i)条-1边计算贡献,则(s_n = sum_{i = 0} ^ {frac{n}{m + 1}} {(-1)} ^ {i} 2 ^ {n - (m + 1) * i} inom{n - i * m}{i})
    则可以根据(m)的大小分类讨论,(m < S)时,用线性齐次递推;否则直接用后面的式子+lucas算。

    Hello, WuXu(LibreOJ Round #8)

    Matching

    糊结论题。注意到(k < min(n, m)),所以一定要匹配(lfloor frac{nm}{2} floor)对才能达到最优。
    (n)是偶数且(m)是偶数时把整个矩阵划分为四个全等部分,左上和右下匹配,左下和右上匹配,且位置相似的匹配。
    (n)是奇数且(m)是奇数时把整个矩阵挖去正中间一块后,划分为四个全等部分,左上和右下匹配,左下和右上匹配,且位置相似的匹配。
    (n)是奇数且(m)是偶数时类似的贪心(所有都可以匹配)。
    (n)是偶数且(m)是奇数时类似的贪心(所有都可以匹配)。

    MIN&MAX I

    首先只有"大小大"和"小大小"会产生贡献。由于这两种贡献对于所有排列而言是完全对称的,可以只考虑一种。
    考虑从大到小加数,计算"大小大"的贡献,可以轻松列出式子

    [E = frac{sum_{i = 1} ^ n max(i - 2, 0) frac{n!}{i}}{n!} ]

    所以答案就是

    [2 left[n + 1 - sum_{i = 1} ^ n frac{2}{i} ight] ]

    后面那个东西用分段打表算。

  • 相关阅读:
    for..of与for..in
    吉凶与祸福之辩证
    console.log(0.2+0.4===0.6)// true or false??
    Javascripte的原型链之基础讲解
    Vue之九数据劫持实现MVVM的数据双向绑定
    Object的方法
    Javscript的函数链式调用基础篇
    Object.keys
    Object.prototype.hasOwnProperty与Object.getOwnPropertyNames
    call和apply还有bind
  • 原文地址:https://www.cnblogs.com/psimonw/p/11725796.html
Copyright © 2011-2022 走看看