zoukankan      html  css  js  c++  java
  • October Challenge 2020 Division 1

    打了两次div2,终于能打div1了,还是挺兴奋的

    Positive AND(10.2)
    Replace for X(10.3)
    Inversions(10.4)
    D-Dimensional MST(10.4)
    Adding Squares(10.4)
    Compress all Subsegments(10.5)
    Rooted Minimum Spanning Tree(10.5)
    Random Knapsack(10.8)
    Village Road Network(未做)

    Rooted Minimum Spanning Tree

    回顾Kruskal算法,令(G_k)为根据kruskal算法生成的有(k)条边的森林
    引理1:任意(k)边森林(T)的最大边大于等于(G_k)的最大边

    证明:
    反证法:假设最大边小于(G_k)的最大边
    (e)为最小属于(T)不属于(G_k)的边,显然其小于(G_k)
    根据kruskal算法流程,(e)加入(G_k)后形成了环,且环中的边比其小,令(f)为在环中某条不在(T)的边(容易证明一定存在)
    (T)更改为(T-e+f),最大边未增加,通过反复操作,可知假设非真

    引理2:任意(k)边森林(T)总重大于等于(G_k)总重

    证明:
    根据引理1,可删除(T)(G_k)最大边
    通过归纳得证

    考虑除(1)以外的集合,初始时有(n-1)棵树,每次合并两个连通块,将两个连通块的两条与(1)相连的边割掉一条,(1)的度数(-1)
    一条边对答案的增量为:重量-两端到(1)的最大值。过程同Kruskal
    考虑正确性:证明引理1依然成立,在(T)(G_k)的边权看作插进来对答案的增量,由于当一条边插入(G)时其他边的增量会增大,这意味着该边增量一直会比其他边小,容易证明引理1的正确性

    但我们需要考虑的是,合并两个连通块后,与这个连通块相邻的边的增量是会发生变化的,如何优化呢?
    对于一条边,其两个端点在不同连通块,其分别加入两个连通块的集合,然后在一个连通块中生效(生效:加入后删掉该连通块与(1)的边)
    用set启发式合并维护这个过程
    (O(mlog^2m))

    Random Knapsack

    肯定是考虑哈希碰撞,预处理(B)个,(O(B+qfrac{mod}{B}k))(其中(k)是哈希的常数)。取(B=10^6)能过(20)
    考虑预处理(2^{20})个,排序后两两之和期望情况下大概是(16000)级别的,如果能过第三个点,那结合那种算法是能过的
    不过我并不知道怎么过第三个点
    考虑将(16000)分开做,先将([0,2^{10}))这些数查询子集(这仅需要过第二个点),再单独查询(2^{10},2^{11},2^{12},2^{13},2^{14})
    对于查询,具体拿多少个数出来给它们还需要调调参
    放份场上的代码code

  • 相关阅读:
    STM32CubeMX 使用
    Zookeeper集群搭建
    golang zookeeper监听事件报错
    git push 报错
    springboot使用postgresql模式下数据库表找不到
    不要在循环中访问数据库,这样会严重影响数据库性能
    SQL查询效率(Oracle)
    游标 数据集 效率比较
    oracle 视图
    INDEX SKIP SCAN 和 INDEX RANGE SCAN以及索引会失效
  • 原文地址:https://www.cnblogs.com/Grice/p/13780596.html
Copyright © 2011-2022 走看看