• ZR提高失恋测2(9.7)


    ZR提高失恋测2(9.7)

    网址http://www.zhengruioi.com/contest/392

    版权原因,不放题面

    A

    首先,我们发现对于匹配串(s)中所有满足(s_i ot = s_{i + 1})(i)

    那么(i)(i + 1)之中至少要一个点被匹配,这应该是比较显然的

    如果不这样肯定不满足条件

    我们首先考虑暴力匹配,能匹配就匹配,这样可以得到一组字典序最小的解法

    但是,这样直接填出来的答案很可能是不对的

    考虑怎么把它给变对

    这样就要用到开头所说的东西

    我们从后向前去枚举满足(s_i ot = s_{i + 1})(i)

    这两个位置肯定是要被覆盖一个的

    我们就看看我们当前匹配的最后一个是(0)还是(1),放到对应的位置上

    如果枚举的过程中遇到了已经匹配到的点,说明我们存在一种方式把前面和后面接起来

    但到最后我们发现无论怎样也无法碰到匹配的点,说明无解

    代码

    B

    感谢xtq大佬的耐心讲解Orz

    首先我们考虑一个比较naive的做法

    二分答案,拆点,一个点拆成(2 imes mid)个点

    ((0/1,i,j))个点表示能否在连续经过(j)条颜色为(0/1)的边之后到达(i)

    直接建图bfs判断连通性即可

    时间复杂度为(Theta(n^2log n))

    我们考虑怎么优化这个东西,一个比较直接的思路是倍增优化建图

    这样加上二分的时间复杂度为(Theta(nlog^2 n))

    但是由于超大常数+我不会写无法通过100%的数据

    考虑如何去优化这一个过程

    我们看看我们暴力在干嘛

    就是寻找所有在(mid)对应颜色步数范围内找到所有能走到的点,并且尝试变换颜色

    上面的算法之所以慢,是因为点数有点多,同一个点因为状态不同可能会被遍历多次

    这显然有些浪费

    因为我们只关心不同颜色的边之间的转移,相同颜色的边我们只关心能否在范围内到达.

    由于每个点都存在唯一后继

    所以我们用并查集维护从当前点向后跳相同颜色的边跳到第一个未被访问的点的前一个点

    之后由于还要维护步数来确定mid的限制,所以我们要使用带权并查集

    我们每次都暴力去跳到当前的根的下一个节点然后判断步数,之后尝试把这个点的相反颜色入队.

    每个点只能由相反颜色扩展过来,并且只会入队一次.

    但是很可能会有环

    我们发现我们尝试跳一步到达的集合的根就是他自己,说明我们跳完了环,直接退出循环就好了

    代码

    C

    谢谢smy不厌烦的指导我才A掉了这道题目,我永远喜欢smy

    神仙常数题

    首先,由于(w <= 10^6)任何权值的不同的质因子的个数不会超过(7)

    之后发现我们直接找最小满足条件的(l)比较难,我们寻找最大的不满足条件的(l')

    那么则有(l = l' + 1)

    也就是说我们现在问题转化成了找到最长的经过((u,v))的gcd不为(1)的路径

    这东西貌似也不大好直接求

    我们设((u,v))之间的gcd为(g)(这一部分可以通过倍增得出)

    存在

    [g = p_1^{k_1} imes p_2^{k_2} imes dots p_n^{k_n} ]

    我们想,一条经过$(u, v) $ 路径 (gcd) 不为 (1),必须要满足他至少存在一个相同的素因子

    所以我们便有了一个想法,对于每个质因子,我们只考虑所有整除这个质因子的边

    然后我们可以得到一颗森林,对这个森林跑一边树形DP

    (d_{i, j})表示点(i)在只考虑第(j)个素因子的贡献时,最大向下的延伸长度

    (d'_{i,j})表示点(i)在只考虑第(j)个素因子的贡献时,最大向父亲的延伸长度

    则两个的必要性应该比较明显

    我们还要设(d''_{i,j})表示点(i)在只考虑第(j)个素因子时,次大向下延伸长度(不能和最大存在于同一个子树中)

    这三个的必要性下面都会讲

    最回到((u,v))

    我们发现有贡献的只有(g)的质因子((g)的定义见上面)

    我们就枚举它的所有质因子,然后这个(l')就是每个质因子的贡献的(max)

    考虑一个质因子(p)

    我们考虑两种情况

    (1):((u,v))不是祖孙关系

    也就是这个样子

    (有点丑不要介意)

    很明显我们只能在((u,v ))的子树中寻找答案

    也会是(d_{u,p} + d_{v,p})

    这种情况比较简单

    (2) (u)(v)存在祖孙关系,我们假设(u)(v)的祖先

    这时候我们就不能像上面那样直接算子树内的,因为他可能出现这种情况

    这就是最长路径的贡献来自同一子树

    这也就是我们要记录(d')(d'')的原因

    首先分析(d_{v.p})肯有贡献

    (u)的贡献实质上是扣去(v)所在的(u)的子树剩下的部分的最大值

    也就是(max(d'_{u,p},x))

    其中(x)的贡献是,如果(u)的最长链的贡献与(v)在同一子树,就是次长链的贡献,负责就是最长链的贡献,

    将两部分贡献合并就是总贡献

    另外无解怎么判断

    如果经过((u,v))的最长路径正好等于(l'),肯定无解

    另外(dp)的时候由于每条边最多只会被计算(7)次贡献,所以(dp)数组开(map)就可以避免MLE

    另外要将素因子放到第二维去维护,可以大大减少log的常数

    代码

  • 相关阅读:
    操作系统
    C++流类库(11)
    C++运算符重载(10)
    C++虚函数(09)
    C++向量(08)
    C++继承(07)
    ResNet实战
    ResNet,DenseNet
    经典卷积网络VGG,GoodLeNet,Inception
    CIFAR100与VGG13实战
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/11502358.html
Copyright © 2020-2023  润新知