口嗨区

因为各种原因不想码或者或码不了,开一个博来记录思路。
在直接抄题解之前先口嗨一顿说明我读过题面。


https://www.luogu.com.cn/problem/P2286

平衡树模板题。
若树中只有同类数据直接插入。
出现异类数据查询前驱后继,选择更接近查询值的作为答案。

2020.5.2


https://www.luogu.com.cn/problem/P3850

单点插入,单点查询。

  1. STL大法好 ! T6: 单点插入,单点查询

  2. 分块大法好 ! T6: 单点插入,单点查询

  3. 平衡树。
    根据输入给出的位置,可得插入数的前驱后继。
    用fhq 按子树大小分裂维护数列。
    插入一个数 = 后继~结尾所有数权值+1,新建一权值为前驱+1的节点并插入。
    插入时的过程

    • 按前驱权值分裂。
    • 右树所有点权值+1。
    • 新建节点并插入。

    grph
    可发现插入新节点之后,不会影响树的性质。

    装上脑子一想之后发现根本没有必要维护权值。
    二叉搜索树的形态就可反映权值大小关系。
    维护权值实际上对按排名分裂的结果没有任何影响。
    我是傻逼,学到许多。

2020.5.2


https://www.luogu.com.cn/problem/P3224

需要查询第 k 小值,则必须维护点集。
怎么暴力怎么来,先考虑维护 n 个平衡树,表示与各点联通的点集。

  • 查询操作 直接查询对应平衡树中第 k 小。
    复杂度 log n
  • 合并操作 枚举 x ,y 两棵树中的点, 将其对应点集两两合并。
    for nodex in x:
       for nodey in y:
         tree[nodex].insert(nodey)
         tree[nodey].insert(nodex)
    
    大概长上面的样子,单次复杂度 n^2 log n (枚举 + 平衡树insert)。

发现瓶颈是点集的合并。由于查询操作已不可优化,考虑优化合并部分。

手玩合并过程,观察可知,合并后各点 对应点集相同。
再推广一下,两个联通点对应点集相同,经过多次合并后仍相同。
维护多个相同的点集 显得有些多余。

发现这玩意长得有点像并查集。
类比并查集的结构,可得到一种维护方法。

维护每一个节点对应点集的树根。
合并时将较小树的点暴力转移到较大树上(类似按秩合并),并将被转移的节点的根更新。
若按秩合并可保证最多只出现n次 insert操作,否则枚举会变成n^2级别。
维护根的关系时使用并查集。

或者直接写一个LCT水过去,就没有这么多事事了。

2020.5.2


http://www.lydsy.com/JudgeOnline/problem.php?id=4998

看起来很有tarjan的感觉。
若加边后,出现一个环,就将这条链split出来,再将链上的所有点摁到一个超级点里。
更新超级点的size 为 其中点的size, 更新其中点的belong。
查询时,两点在同一超级点中,就输出size。

2020.6.7


http://www.lydsy.com/JudgeOnline/problem.php?id=2959

上面那道题的加强版。不看样例还以为是牛逼题,先喷一波狗屁不通题面描述。
如果按照题目给出要求:

为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。

显然,如果进入了一个超级点,可以在里面绕圈圈刷卡。
观察样例可知:

  1. 可以在一个点里绕圈圈。
  2. 到达终点之后不一定立即停下,可以继续绕圈圈再回来。
    那这题就贼水了。

两点之间的答案即为 两点路径上所有点,
所在超级点的size之和。
同上题维护即可。

posted @ 2020-05-02 09:38  Luckyblock  阅读(101)  评论(0编辑  收藏  举报