一些常见实用的套路【更新中】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hzj1054689699/article/details/83217117

数据结构

  • 在维护树上路径时,如果只是点的独立的加减,可以考虑用括号序来维护(拆成两部分)
  • 需要求树上很多路径中k近/距离和 一类,考虑点分治/在点分树上解决。
  • 子树求和可以转化为DFS序上区间求和
  • 树状数组可以区间查询/修改(差分)
  • 需要查询序列上区间数据结构,只要满足总和是可以接受的范围,可以用线段树,每个区间维护一个这样的数据结构(例如AC自动机等)
  • 多维偏序问题,排序可以降维,CDQ分治可以降维,剩下只需要树状数组/线段树
  • 树上连通块有概率出现,再加上和的次方,往往可以拆开来,变成任意选K个可重,有序的点,考虑贡献。
  • 当又需要分块,每个块维护数据结构时,块的大小考虑调整(不再一定是 n \sqrt n )(平衡规划)
  • 同理,对于图论中度数总和固定、多组询问查询的点数固定,查询点需要枚举出边,但可能一直查询度数比较大的点。此时考虑平衡规划。(询问点个数/度数 大于/小于 n \sqrt n 分开来做)
  • 对于点分治时两个不同的子树的结果混在一起需要判掉,可以考虑几种办法:
    • 在点分树上儿子记录当前点分树子树中的节点到父亲的结果,计算父亲时在这里减去。
    • 维护DFS序,两个子树对应两个无交的区间,可以考虑区间分裂一类的做法。
  • 对于有很多颜色的点,需要对相同颜色计算影响,可以把每个颜色拉出来在DFS序上搞事情(相邻+1,lca-1一类)
  • 如果又加上了深度限制,那么相当于除了DFS序这一维,还多出了深度这一维,可以考虑(主席树/CDQ分治/二维数据结构)
  • 对于这样一类问题:每个元素(边/点之类)具有权值/权值范围,每次只需要考虑权值是一定值/一定范围的元素的影响,可以考虑建立权值线段树,将元素的影响挂在线段树对应的所有区间上,查询就查询区间。
  • 当需要查询树上是否存在一条路径过两个点时,可以将路径端点记在DFS序上,然后两点子树查询,这就变成了两个区间数点的问题(二维偏序/扫描线/DFS动态树状数组维护增量)

图论

  • 求点双连通分量栈中仍然可以存点,圆方树维护起来很方便。
  • 无向图中最大值最小的路径一定在最小生成树上
  • 合并两个连通块的直径,直接比较四个端点两两连起来的长度即可。
  • 一些有代价的完美覆盖问题,选格子有行列限制有代价/收益的题往往考虑网络流。

其他

  • 如果遇到 n 3 n^3 的转移矩阵,但是我们一次只想知道的结果是一维的(即暴力乘的复杂度是 n 2 n^2 ),那么可以考虑倍增预处理转移矩阵的幂,求出转移矩阵 2 0 , 2 1 , 2 2 . . . 2^0,2^1,2^2... 次的结果。询问的时候只需要 n 2 log n^2\log 而不是 n 3 log n^3\log ,预处理则是 n 3 log n^3\log ,总的复杂度就可以变成 q n 2 log + n 3 log q*n^2\log+n^3\log

猜你喜欢

转载自blog.csdn.net/hzj1054689699/article/details/83217117