zoukankan      html  css  js  c++  java
  • 「LCT」

    终于在多篇题解和我的个人超常发挥完了lct的所有题,kx死了。

    理解

    在我看来,实际上lct的板子没有什么考的,更重要的可能是起到一个数据结构的维护作用实际上就是出题人想给你找点乐子。

    前几道题都还是基础类型,到后面真的是颓题解都不太懂系列,还是有很多东西要学啊。

    例题

    A. Cave 洞穴勘测

    其实我发现数据结构专题都不用写题解的这个。

    码就完了。

    B. 树的维护

    新get了一个边化点的以后就会变成常识套路。

    维护最大值最小值,变成相反数就交换加负号。

    C. tree

    这道题需要维护加法乘法两个懒标记,我的做法是乘法优先,如果此时有加法标记就给它乘上。

    除了调死我了我还有什么好说的呢

    D. 水管局长数据加强版

    通过B哥的题解记起了还有时光倒流这种远古方法。

    E. GERALD07加强版

    调了一晚上

    通过B哥的题解

    类似数颜色?维护每条边的pre表示这条边被谁取代,维护一个森林,如果加上这条边成环了就删掉最历史悠久的边,然后主席树,查询时查询区间内小于L的数个数。

    G. 难存的情缘

    唔...同树的维护?


    A. 魔法森林

    题目求A+B的最小值,其中A为$max{a}$,B为$max{B}$,这样就会发现其实A和B的贡献可以分开算。

    那么就有一个套路了:把所有边按A升序,然后每加入一条边A的最大值就已经确定,只需要得到B的最大值最小就好了。

    如果不选这条边确实A的最大值不会是这条边,但不会影响答案最小解啊。

    B. 大森林

    大神题警告!做了一晚上+半上午剩下半上午用来颓废

    不看题解真的是无从下手。因为这n棵树关系不定,而生长节点又是什么玩意啊。

    应该把操作一看成把一些节点刚开始长在最初的生长节点,到L树时把这些节点挪到x节点,到R+1树时再给它挪回去。

    操作零实际上可以省去范围,因为多建点对询问并没有影响,又没有长在路径上。

    操作一看成在x这棵树时查询两点间的距离。

    所以实际瓶颈在如何在正确的复杂度内执行操作一。

    建虚点。这样就可以直接把点都建在对应的虚点下,该挪移的时候就直接$cut link$虚点和对应的生长节点了。

    因为建立了虚点,又需要统计路径,只好给每个点赋点权,实点赋1,虚点赋0。统计答案不能用split,因为此时两点间的路径由于虚点的建立已经被破坏,而由于每个点到根的路径不变,所以我们可以split(u),得到$sum_1$就是u到根的深度,再split(v),split(lca)就得到答案了,怎么得到lca呢?access u时又在access v时出现的深度最大的点就是答案。

    注意节点有生活范围,1操作的换生长节点操作要和x节点的生活范围求交。1节点也要记录生活范围,不然会对拍2h到自闭(然后被神啵茬1min精准定位错误)

    可以makeroot啊,只要保证求解时根不变就对了。

    C. 情报传递

    Dybala說的思博题我还是颓了题解....我怕是要完

    看透了传递情报的C的含义:求i-C-1前的搜集情报人的数量和。

    求参与传递的情报员相当于求split后根的siz大小,危险情报员就是链的权值。

    D. 在美妙的数学王国中畅游

    真想不到。

    泰勒展开就可以lct维护系数了,导15,16次就可以够精度了。

    微积分快去颓nc哥。

    神啵茬又一次1min切掉我调了一万年的错误。

    E. LCA

    只想到了分块思路,还卡了半天的常。

    分块。

    维护每一块对每一个z的贡献。O($nsqrt n$)

    这里的dfs没想出来。

    对于块内的每个点,它自己的值先设成1。然后统计子树内有多少个点,这就是这个点的贡献,再统计一次前缀和,就是这个块对z是这个点时的深度贡献。

    边角暴力求lca的dep。O($msqrt n$)

    必须用O(1)LCA。必须变深搜为广搜

    正解是差分,把区间查询变成了查询$(1,r)-(1,l-1)$的贡献。

    修改相当于是区间+1,查询相当于取区间和。

    F. 即时战略

    交互题第一次做。二话不说颓题解。

    对于链的情况需要特殊处理,也很好处理,建一个双端队列,每次选择一个没有遍历的点为目标。

    取队首explore。如果更新出新的点,就一直更新。否则就一定是队首后边的元素,就直接跳到队尾不断更新就完了。

    对于其它情况,可以用lct。还是选择一个未更新的点,接着从1开始explore。因为有可能跳了很多次都是已经遍历过的点

    所以定义$L_i R_i$表示在splay上i跳到的最小深度的节点和最大深度的节点,也就是以i为根的splay向左向右的链的尾点。

    那么对于节点i explore到的点j。有四种情况。

    一:没遍历过。i跳到j,并把j的父亲设成i,相当于建虚边。

    二:j=R[ch[i][0]]。也就是i上边的点。i跳到ch[i][0],相当于跳到了j的上边一半(平衡状态),等价于二分链位置。

    三:j=L[ch[i][1]]。也就是i下边的点。i跳到ch[i][1]。

    四:是其它splay里的点,就跳到那个splay的继续找。这里如果选择把跳到的j splay到根而不是跳根的话就过不了hack数据。

    之所以要跳到根,因为要二分目标节点的位置,自然,根最平衡啦。

    最后找到目标节点后还要access,使splay数量尽可能少。

    还不能makeroot。不知道为啥。

  • 相关阅读:
    poj 1860 Currency Exchange(最短路径的应用)
    poj 2965 The Pilots Brothers' refrigerator
    zoj 1827 the game of 31 (有限制的博弈论)
    poj 3295 Tautology (构造法)
    poj 1753 Flip Game(枚举)
    poj 2109 (贪心)
    poj 1328(贪心)
    Qt 对单个控件美化
    Qt 4基础
    Bash Shell
  • 原文地址:https://www.cnblogs.com/hzoi2018-xuefeng/p/12080870.html
Copyright © 2011-2022 走看看