模拟56 题解
A. Merchant
看到一次函数,马上想到维护一个凸包,或许可以维护一下前m大一次函数的总和?
然而想了想并不会维护,于是转换了下思路。
似乎答案具有单调性:除去答案为0的情况,其它一定具有单调性。
结论是显然的。
不妨考虑任何一个组合。
一些一次函数的和仍为一次函数。
如果总一次函数的斜率大于0,那么时间越大越优,即具有单调性。
如果总一次函数的斜率小于等于0,那么时间为0时最优,所以答案必定为0。
然后就可以二分答案,找前m大统计。
然而暴力$sort$,复杂度是$O(nlog^2n)$的,并不能过掉$n=10^6$。
使用$nth_element$,其实也是使用了快排思想,只不过递归一半,平均复杂度为$O(n)$。
然而有一些细节:
如果当前值小于0,那么不统计这个答案。
可能会加爆$longlong$,可以在超过$s$时马上$return$ $1$。
其实写$sort$的时候注意了这些细节,然而后来改$nth_element$的时候就忘记了。
B. Equation
给定的树上方程比较简单。
随便推一推就可以将$x_i$表示为$x_1$和常数。
发现这个常数其实只与祖先链上的权值有关。
所以用dfs序建树状数组,维护一下这个常数是什么。
加上给定的一个方程,总共三个方程,手动解就可以了(当然对这三个方程打高斯消元复杂度也是对的)。
C. Rectangle
考虑枚举计算矩形的左右边界,那么左右边界必须各选一个点。
首先是比较简单的形式:左右边界各有一个点,那么这两个点必选。
那么矩形的上下区间至少为当前左右边界的$y$值,分别设为$y_{mn}$,$y_{mx}$。
答案与区间内部,小于$y_{mn}$和大于$y_{mx}$的$y$值有关。
答案为$(r-l)*\sum \limits_{y_i<y_{mn}}^{} \sum \limits_{y_j>y_{mx}}^{} y_j-y_i$。
用树状数组维护一下区间的$sz$和$sum$,就可以查询了。
考虑更为一般的情况:
左右边界上有更多的点。
那么通过这些点把整个$y$值域划分为若干个区间。
每个长度跨过一个区间的$y_j-y_i$都应该被计算到一次且仅一次。
从小到大考虑每一个区间,注意一下开闭就可以了。