=======WQS二分======= * wqs二分可以解决形如在$n$个物品中选$k$个物品最大化/最小化总价值。直接dp一般是$O(nk)$的,而如果题目满足下面的条件并且可以用$O(n)$时间在不考虑选择物品个数的情况下计算出最大值/最小值,就可以用wqs二分做到$O(n \log n)$。 * 以最大化价值为例,设$x$表示选择物品的个数,设$f(x)$表示选$x$个物品的最大值,如果$f(x)$关于$x$是凸函数或凹函数,那么图象就是一个凸包。虽然我们不知道具体凸包长什么样,但是我们可以利用凸包的性质,通过二分直线的斜率使得这条直线与$(k,f(k))$这个点“相切”,从而间接得到$f(k)$的值。 * 以凸函数为例,由于图像是一个凸包,所以一条直线,如果想让直线与图象有交点的情况下截距最大,那么直线一定恰好经过凸包上的一个点,此时我们通过下面的方法求出这个点后,如果这个点的横坐标$void dfs(int i, int fa){ f[i][0] = Data(0, 0), f[i][1] = f[i][2] = Data(-mid, 1); for(int j = 0;j < v[i].size();j++){ int x = v[i][j].first, y = v[i][j].second; if(x == fa) continue; dfs(x, i); Data g = max(f[x][0], max(f[x][1], f[x][2])); f[i][2] = max(f[i][1] + f[x][1] + Data(y + mid, -1), f[i][2] + g); f[i][1] = max(f[i][0] + f[x][1] + Data(y, 0), f[i][1] + g); f[i][0] = max(f[i][0], f[i][0] + g); } } =====Tree I===== * 题意:给出一个$n$个点的图,每条边有权值和黑白色两种颜色,求恰好有$k$条白边的最小生成树。 * 题解:设$f(x)$为选$x$个白边的最小生成树,这个函数是下凸的。给每个白边减去$mid$跑Kruskal即可。这里优先选白边,那么每次得到的是数个共线点中最靠右的点,二分边界时要注意一下。 =====CF1279F===== * [[educational_codeforces_round_79_rated_for_div._2_virtual_participation|F题]]