zoukankan      html  css  js  c++  java
  • 「NOI 2021」题解

    代码托管到第三方平台上。

    NOI2021 题解

    D1T1 轻重边

    水题

    D1T2 路径交点

    卡常的水题

    考虑 (k=2) 的情况,每种路径方案都可以使用一个排列来描述,排列的逆序对数量就可以用来描述交点数。

    因此,设矩阵 (Min R^{n_1 imes n_1},M_{ij}=[(i,j)in E])​​,那么自然而然地得到 (k=2) 时答案为:

    [det(M)=sum_{p}(-1)^{sigma(p)}prod_{j=1}^{n_1}M_{j,p_j} ]

    考虑 (n)​ 相等的情况。由于 (k>2)​ 时,各层的逆序对为叠加关系,因此各层的行列式乘法时 (-1)​​​​​ 的指数就会相加,满足系数要求;同时,将行列式相乘也相当于枚举了每一种可能的方案,因此可以得到答案:

    [prod_{j=1}^{k-1}det(M_j)=det(prod_{j=1}^{k-1}M_j) ]

    最后考虑 (n)​ 不相等的情况,根据 (n_k=n_1)​ 的限制不难想到 (det(prod_{j=1}^{k-1}M_j))​ 就是答案。顺向思考,考虑任意一种路径方案,必然可以被描述为:首先,从 (2sim k-1) 的每一层中选择一个大小为 (n_1) 的子集,接着就化归到了 (n) 相等的情况,最终我们需要对所有的子集方案求和;可以发现这就是 Cauchy-Binet 公式的形式,因此我们的猜想是正确的。

    本题有亿点卡常,不建议写成矩阵乘法,建议写成类似于 DP 的形式,最终复杂度即为 (O(Tn_1sum m))

    D1T3 庆典

    还不错的题目。

    简单转化:题目中“可能经过 (u)”等价于“既能从 (s) 到达 (u),也能从 (u) 到达 (t)”。

    首先考虑 (m=n-1)​​ 的部分分,不难论证得出此时图的形态必然是一棵外向树。对于普通的点,它们仅能从祖先的点到达,仅能到达子树内的点。而题目给出的 (k) 条边仅仅会影响 (2k) 个点的可达性与到达性,其余的点的可达性、到达性仍然可以”借用“祖先的点和子树的点来描述。

    这样,我们不难想到,最终可以经过的点就可以被描述为 (2(k+1))​ 个关键点之间的某些链的并集。合法的链即”从 (s) 可以到达链头,且从链尾可以到达 (t) 的链“。注意到 (k) 很小,因此可以暴力 Floyd 求出传递闭包,接着枚举每条链,最后做一个树上链并即可。

    还需要注意,新加入的 (k)​ 条边也可以被算作合法的链,但是显然这样的链只有端点有效,因此打一下标记即可。

    最后解决 (m ot=n-1)​ 的情况,将强连通分量缩点之后,题目的性质在新图上仍然满足,缩点后直接跑。

    小结:注意图的形态,缩点后保持树形注意答案的形态,一定是链并

    复杂度可以做到 (O(nlog_2n+qk^3))

    D2T1 量子通信

    不错的乱搞题目,正好戳中我的痛点。

    由于 (kle 15)​,因此有变化的部分会很少;同时,如果我们将一个单词划分为 (16)​ 段,每段长度即为 (16)​,那么 (k)​ 次修改最多会带来 (15)​​ 段变化,也即,必然会有一段保持不变。因此对于询问串,我们可以枚举保持不变的一段,并检查在枚举段相同的单词中是否有差异不超过 (k) 的单词。

    由于字典中的单词随机,因此每一段中,某种情况的单词期望个数为 (frac{4 imes10^5}{2^{16}}approx 8);此外,计算差异数可以用 __builtin_popcountll 做到 4 次运算,因而复杂度为 (O(n+q)),其中 (n) 的常数约为 64, (q) 的常数约为 512。

    小结:一定要多多注意小数据的处理方式,在这道题中就根据较小的修改次数和较长的长度,运用鸽巢原理大幅缩减所需检查的字符串的数量(这应该是查找类题目的重要思路)。

    D2T2 密码箱

    容易发现 (f)​ 计算的是一个连分数:([a_0;a_1,a_2,dots,a_n])​​

    考虑递推计算,设 (f_k=[a_k;a_{k+1},a_{k+2},dots,a_n]=frac{p_k}{q_k})​​;特别地,边界 (f_n=frac{1}{a_n})​​。

    那么递推关系为:

    [f_k=a_k+frac{1}{f_{k+1}} ]

    也即:

    [egin{aligned} p_k&=q_{k+1}+p_{k+1}a_k\ q_k&=p_{k+1} end{aligned} ]

    这组递推式有两个作用:

    第一,根据递推式可以发现 (gcd(p_k,q_k)=gcd(p_{k+1},q_{k+1})),在边界处 (gcd(p_k,q_k)=1),因此中途结果均保持既约性质,不需要约分;

    第二,递推式是线性的,这表明递推过程可以用矩阵来描述;设 (F_k=egin{bmatrix}p_k\q_kend{bmatrix},M_k=egin{bmatrix}a_k&1\1&0end{bmatrix}),则 (F_k=M_kF_{k+1})

    注意到这个转移与 (a)​​​ 相关,而为了维护操作序列的变化,我们最好是将 WE 直接用矩阵来描述。

    容易发现 W 其实就是矩阵 (egin{bmatrix}1&0\1&1end{bmatrix});而考虑 E 操作,当 (a) 的最后一个元素不为 1 的时候,E 等价于矩阵 (egin{bmatrix}1&0\-1&1end{bmatrix}egin{bmatrix}1&1\1&0end{bmatrix}egin{bmatrix}1&1\1&0end{bmatrix}),而当 (a) 的最后一个元素为 1 的时候,这个矩阵乘上以后得到 (egin{bmatrix}1&1\1&0end{bmatrix}egin{bmatrix}1&0\-1&1end{bmatrix}egin{bmatrix}1&1\1&0end{bmatrix}egin{bmatrix}1&1\1&0end{bmatrix}=egin{bmatrix}1&0\1&1end{bmatrix}egin{bmatrix}1&1\1&0end{bmatrix}),施加上以后恰好等价于“先去掉最后一个元素,再给最后一个元素 +1,再在末尾添加一个 1”,也就是给倒数第二个元素 +1。

    因此直接用平衡树维护矩阵积即可,细节有亿点多。

    小结:从部分情况入手,逐步推广的思路很好用;尤其是在本题中,E 的操作看起来构造性很强,其实也暗示它很有可能就是某一特殊情况简单推广后的结果。

    D2T3 机器人游戏

    非常棒的题目,质量很不错

    样例 2 的解释贴心地给出了容斥计算的解释,直接模拟可以得到一个 (O(2^nn^2m))​​ 或者 (O(2^nnm))​​ 的容斥做法,这里就不详细解释了。

    但是这个做法还需要优化。不难发现对于每个格子的四种操作:不变/赋 0/赋 1/取反 构成了一个群,以下我们分别用 0/1/2/3 表示这四种操作。

    我们只需要考虑每个格子被操作覆盖的情况即可计算出方案数。在较差的复杂度中,我们可以直接预处理每种情况的方案数;为了优化,我们需要细致分析。假如一个格子同时被 0,3 覆盖,或者同时被 1,2 覆盖,那么它只能输入输出都为空,因此方案数为 1;假如一个格子被 0/3 其一覆盖,同时被 1/2 其一覆盖,那么它除空外只有一种方案,因此方案数为 2;在其它情况下,方案数均为 3。

    需要注意,如果某个格子并未被容斥集合中出发的每机器人次覆盖住,那么该格子便隐式地被 0 覆盖。

    那么,对于任意容斥集合 (P)​,使用 unsigned 我们不难处理出操作 (o)​ 影响到的格子的集合 (f_{P,o})​​,按照上面的分析处理出不同情况的位置集合计算即可。

    如此我们得到了 (O(2^nm)) 的容斥。


    为了方便描述,设 (r_j) 表示机器人 (j) 影响到的格子个数,也即字符串中 R 数量 +1。

    注意到极限数据为 (n=32)​​​,恰好为 (16)​​ 的两倍,这启示我们折半处理容斥集合。对于仅包含左边 (16)​​ 个位置的容斥集合,我们可以直接枚举并计算;对于包含右边 (16)​​​ 个位置中任意一个的容斥集合,我们注意到此时贡献非 1 方案数的机器人必然满足 (r_jle n-max Ple frac{n}{2}),其中 (Psubseteq {0,1,2,dots,n-1},exist pge frac{n}{2},pin P)​​​​。

    由于每个位置仅会受前 (r_j)​​​ 个位置影响,因此我们可以枚举 (P)​​​ 中最大值后直接 DP,状态 (f_{i,S,0/1})​​ 表示前 (i)​ 个位置,其中 ([i-frac{n}{2}+1,i])​ 的选择情况为 (S)​,在 ([0,i-frac{n}{2}])​ 中无/有选中的位置的情况下,容斥的结果。其中每个位置的贡献也可以预处理,(c_{S,0/1,k})​ 表示对于某一位置,若 ([i-frac{n}{2}+1,i])​ 的选择情况为 (S)​​​,在范围外无/有选中的位置的情况下,所有 (r_jle k)​ 的机器人的贡献。

    DP 结束后还需要计算最大值之外的位置的贡献,用好 (c) 即可。

    这部分复杂度为 (O(m2^{frac{n}{2}}+n^22^{frac{n}{2}}))


    将两个做法结合在一起即可得到正解。

    小结:在降低复杂度的过程中,精细的分析是很有必要的,有时候需要借助比较暴力的预处理,不过在本题中仍需要进一步分析;此外,本题的复杂度平衡依托于当包含的元素都靠前时,容斥集合包含的位置较少;当包含的元素靠后时,有效的机器人 (r) 较小,出现这样的 (min)​ 限制的时候需要注意是否可以平衡复杂度。

  • 相关阅读:
    eureka的fetch-registry属性解释
    数据结构设计
    typescript let和const区别
    JDK8新特性
    Synchronized的内存可见性
    java实现打印功能
    idea单元测试jpa注入失败问题----来自Spring Cloud微服务实战-idea版的 廖师兄的product
    eclipse快速生成接口
    读取 Excel 之 Epplus
    [转][Dapper]参数化查询慢
  • 原文地址:https://www.cnblogs.com/crashed/p/15104845.html
Copyright © 2011-2022 走看看