zoukankan      html  css  js  c++  java
  • [学习笔记]优化基础技巧

    只能说确实挺基础。
    集合起来写写吧。

    二分系列

    二分

    略。

    三分

    对于传统的定义域在实数上的凸函数求最值,可以使用三分法。

    lmid = l + ((r - l) >> 1);
    rmid = lmid + ((r - l) >> 1);
    if(cal(limd) > cal(rmid))
    r = rmid;
    else
    l = lmid;
    

    对于凸函数的二分

    OI里凸函数大多为横坐标差相等的离散函数,我们知道凸函数的导数有单调性,又知OI里是离散的,所以我们直接
    二分位置,求\(\Delta\to 0\)的位置即最值位置。

    分数规划

    一般来说分数规划求如下问题
    若干物品有两个权值\(a,b\),选出若干物品使得\(\frac{\sum a}{\sum b}\)最小/最大。

    同时可能会有一些奇怪的限制,比如“分母至少为\(W\)”,我会在这个学习笔记配套的练习里说。

    我们对该问题采取二分法。
    二分答案后我们转为\(check\)
    \(\frac{\sum a}{\sum b} > mid\)
    即可知\(\sum a - mid * \sum b > 0\)
    \(\sum a - mid * b > 0\)
    求出左侧柿子最大值即可。

    凸优化

    一般的问题为强制选出\(k\)个,求最优方案。

    我们设\(g(i)\)\(i\)个物品的最优方案。

    然后我们需要证明或大胆猜想:\((i,g(i))\)有凸性。

    既然有凸性,依旧根据导数那套理论,其每个点的切线斜率有单调性,那么我们可以二分斜率\(k\),并根据其所对应的点的横坐标调整斜率最终使其切到\((m,g(m))\)

    那么我们的目标为判断有一条斜率时,如何求出切点位置。

    image

    观察可得,在上凸包时,其切的点一定为在\(y\)轴上截距最大。

    不妨设\(f\)为截距。

    则一条直线表现为\(y - f = kx\)

    代入点\((i,g(i))\),则有\(g(i) - ki = y \to \sum (a_i - k) = y\)

    即给每个点权值减去\(k\),求最大的情况下选取的横坐标,此时\(g(i) = ki + y\),并以此调整。

    在二分时有整数域和实数域差别,在练习时说明。

    分治系列

    基于时间顺序的分治

    如果要求计算分治中心左右两部分信息的合并,这两部分求值的先后顺序并没有要求。如果要求计算较早操作对较晚操作的影响,那么可以通过处理左子树的信息,来计算左子树对右子树的贡献。

    其思想类似于操作分块,都是考虑操作的并是否能用简单的信息代替。

    具体细节见[学习笔记]CDQ分治

    线段树分治

    处理如下这类问题:

    • 修改具有时效性,即只对\([l,r]\)时间内查询有效果
    • 查询某个时间的答案

    考虑把询问看做线段树叶子节点,则一个修改等同在线段树上打永久化标记,然后查询等同于该叶子节点到根节点的操作的并,我们直接使用可回退数据结构在树上\(dfs\),则其空间复杂度\(O(nlogn)\),时间复杂度为\(O(nq() + np())\),其中\(q()\)表示为插入一个操作的复杂度,\(p()\)为撤销一个操作的复杂度。
    值得注意的是可以使用清除效率高的数据结构,我们直接暴力遍历每条链。
    其复杂度更改为\(O(nlognq() + nclear())\),\(clear()\)为清空所有操作的复杂度。

    基于分治中心性质的写法

    如果分治中遵循先递归左儿子,再递归右儿子,用一个指针去跟踪分治中心,则该指针移动的总距离为\(O(nlogn)\)

    整体二分

    考虑一类能二分答案的问题,可以将所有询问都一起二分,然后判断其分治中心的单调性,然后再分开询问接着二分。
    一个询问只会在分治树上每一层出现一次,其复杂度为\(O(QlogV)\).

    但考虑一类问题,如果无法快速单点求值,但其相邻处非常求,可以利用好分治中心移动的距离不大的性质。(一个经典问题是背包问题,加入一个物品或减去一个物品)。

    分治转移斜率优化

    实际上就是整体二分转移点,因为转移点单调,所以有简单的写法。

    有经典例题在练习记录中给出。

    树分治

    淀粉质。
    变粉质。
    淀粉树。
    动态淀粉树。

    还是到时候另外写一篇博客好了。

    启发式合并

    基础 和 树上轻重启发式合并

    略过不讲。

    长链剖分 即 深度启发式合并

    按深度合并。

    主要来证明一下复杂度\(O(n)\)

    一个点单独被操作时,其一定是在重链顶端。

    值得注意的是,其因为被合并时其深度遍历集合一定被重儿子里的深度集合覆盖,所以确保了复杂度。

    所以就是\(O(n)\)

    倍增

    可以处理多查询,信息可合并的题目。

    扫描线

    典中典,略。

    分块

    数论分块

    即对求\(sum_{i = 1}^b \lfloor\frac{n}{i}\rfloor * f(i)\)

    \(f(i)\)做前缀和,\(\lfloor\frac{n}{i}\rfloor\)只有根号个区间,我们根号个一起处理。

    其中\(\lfloor\frac{n}{i}\rfloor = \lfloor\frac{n}{l}\rfloor\)的最大右端为\(\lfloor\frac{n}{\lfloor\frac{n}{l}\rfloor}\rfloor\)

    int ans = 0;
    for(int l = 1, r = 0; l <= n; l++) {
        r = n / (n / l);
        // do something
    }
    

    操作分块

    当信息合并复杂度较高的时候,可以考虑定期合并,并且额外考虑零散元素的贡献。

    「APIO2019」桥梁 操作分块+带权并查集 LOJ3145

  • 相关阅读:
    hdu2476
    zoj3469 区间dp好题
    区间dp好题cf149d 括号匹配
    cf1108e 线段树区间更新+扫描线
    完全背包记录路径poj1787 好题
    cf1104d二分+数学
    01背包专题
    hdu1069线性dp
    有源汇的上下界最大流
    有源汇的上下界最大流
  • 原文地址:https://www.cnblogs.com/dixiao/p/15682861.html
Copyright © 2011-2022 走看看