- A. Salty Fish
- B. Nonsense Time
- C. Milk Candy
- D. Radar Scanner
- E. Snowy Smile
- F. Faraway
- G. Support or Not
- H. TDL
- I. Three Investigators
- J. Road Manager
- K. Monster Hunter
- L. Game Prediction
题意:有$n$个未知数,然后$m$个人有提示。第$i$个人有$c_i$条提示,每条提示会告诉你$l_j$到$r_j$的未知数的和,需要花费$w_j$的代价。现在你可以买提示,对于第$i$个人,你要么不买,要么恰好买$k_i$个提示。求出能够计算出$n$个数的最小代价。
题解:对于一个提示,我们可以把$l_j-1$和$r_j$连边,显然如果能够买到的边包含一个生成树就可以计算出所有解了。那么考虑那些不买的边构成的集合,显然这个是一个dual graphical matroid
。然后每个边集我们最多不买$c_i-k_i$,这个也是一个拟阵。我们求出这两个拟阵的带权拟阵交即可。如果拟阵的大小不是$\sum c_i-k_i$就是无解。
题意:给出空间中$n$个球,第$i$个在$(x_i,y_i,z_i)$,半径为$r_i$。定义两个球$i$和$j$的距离如下
给出$k$,输出前$k$小的距离。
题解:考虑二分答案$\lambda$,给每个半径都加上$\frac{\lambda}{2}$,转变成求是否存在至少$k$对$(i,j)$他们之间的距离是$0$。
假设全部球的半径都是$R$,那么建立以$2R \times 2R \times 2R$的立方体为单位建立坐标系统,考虑把球$i$放入$(\lfloor \frac{x_i}{2R} \rfloor, \lfloor \frac{y_i}{2R} \rfloor, \lfloor \frac{z_i}{2R} \rfloor)$对应的立方体里面。那么对于一个球$i$,只会和相邻的$3 \times 3 \times 3$的$27$个立方体里的球相交。然后显然,如果一个立方体里存在$O(\sqrt{k})$个球的话,我们一定能够找到$k$对相交的球。
但是现在球的半径不一样,那么先从最大的半径$mR$出发,只考虑$R_i \ge mR$的球。然后把$mR$减半,重复上面过程。这样结论也是成立的,并且只会做$O(\log mR)$次。
假设我们二分的结果是到$\lambda$,但是这时候求出来的$k$对球可能不是我们想要的答案。但是,第$k$个的距离肯定是$\lambda$。我们考虑把$\lambda$减$1$,再做上述过程。那么假设求出来的不足$k$对,不够的肯定都是$\lambda$。如果够的话,就直接输出这$k$对即可。
题意:给出一个长度为$n$的序列$a_1,a_2,\dots,a_n$,对于每个前缀,你需要选出最多$5$不相交的上升子序列,使得他们的权值和最大。
题解:考虑权值都是$1$的话,就是个杨表题。每次插入一个数,然后求出前$5$行的长度之和。那么对于这个题的话,考虑把第$i$个数拆成$a_i$个$a_i$,每次操作把这$a_i$个数挨个插进去,之后再求前$5$行的长度之和的话就是我们这题的答案。
考虑到杨表里很多元素都是一样的,我们其实可以只维护每个数$x$出现次数$y$。然后你插入$a$和$b$的话,就是找到比$a$大的$b$个数,从当前杨表里删除,插到下一个杨表里面。可以发现每次插入一对$(a,b)$的话,最多只会使一对$(x,y)$分裂。因此均摊下来复杂度是$O(2^5 n \log n)$的。
题意:有一棵$n$个点的有根树,$1$是根。除了根节点,每个节点$i$有个怪物,打这个怪兽需要消耗$a_i$的HP,之后会获得$b_i$的HP。必须把祖先节点上的怪物都打死后,才能打当前点的怪物。问最少需要多少HP才能打掉所有的怪物。
题解:考虑没有任何限制的情况,我们肯定优先打$a_i < b_i$的,然后是$a_i = b_i$的,最后是$a_i > b_i$的,其他情况:
-
对于所有$a_i < b_i$的怪物,那么肯定先打$a_i$比较小的;
-
对于所有$a_i=b_i$的怪物,谁先打无所谓,不如也先打$a_i$比较小的;
-
对于所有$a_i > b_i$的怪物,我们肯定要先打$b_i$比较大的。
那么假设按照上述规则,我们排出了一个打怪顺序$p_1,p_2,\dots,p_n$,考虑$p_1$:
-
$p_1$ 的父亲已经被打死了,那么我们直接打这个怪物即可。 -
$p_1$ 的父亲还没有死,那么如果我们打死了$p_1$的父亲后,我们肯定要先来打$p_1$,于是可以考虑把这两只怪合并。
上述两种情况下,我们都把问题从$n$的规模缩小到了$n-1$。因此需要拿一个优先队列来维护最先应该被打的怪即可。
接下来考虑如何合并两个怪$(a_1,b_1)$和$(a_2,b_2)$,成为$(a_3,b_3)$。显然有$a_3 \ge a_1$,因为我们要先打死第一个。这个时候我们的HP为$a_3-a_1+b_1 \ge a_2$,得到$a_3 \ge a_2+a_1-b_1$。于是$a_3=\max(a_1,a_2+a_1-b_1)$,那么$b_3=a_3+b_1+b_2-a_1-a_2$。
题意:有$n$个数$a_1,a_2,\dots,a_n$。有$q$个询问,每次给出一个区间$[l_i,r_i]$,要求用$a[l_i..r_i]$这些数玩如下博弈:每次可以从左端或者有端拿走一个数,每个人目的是最大化自己拿走数的和。求最优操作下,先手和后手数的和多大。
题解:参考这篇论文An Optimal Algorithm for Calculating the Profit in the Coins in a Row Game的结论,加上数据随机,我们可以把问题规模缩成$O(\log n)$的。直接线段树暴力维护即可。
别解:参考这个回答
First of all, I would like to recall the central property of the game: We can replace three consecutive elements
$a_{i - 1}$ ,$a_i$ and$a_{i + 1}$ with$(a_{i - 1} - a_{i} + a_{i + 1})$ without changing the value of the game, if$a_{i - 1} \leq a_i \geq a_{i + 1}$ holds. Repeating the replacement, we ultimately end up with a sequence$b$ such that$b_1 > \dots > b_i < \dots < b_n$ for some$i$ , which is called the reduced sequence as follows. Let the sorted version of the sequence$b$ is$b'$ . The value of the game is essentially$b^\prime_1 - b^\prime_2 + b^\prime_3 - \dots$ .Now back to the
$O((n + q) \sqrt{n} \log n)$ algorithm. Partition the sequence into$\frac{n}{b}$ consecutive blocks of size$b$ . We first compute the reduced sequence of the range$[i \cdot b, j]$ by adding elements to the right. This is can be done in$O(\frac{n^2}{b})$ .To answer a query, we start from a precomputed reduced sequence, and add
$O(b)$ elements to its left. This should be done with the help of a binary search, leading to$O(b \log n)$ time overall. The other difficulty is how to calculate the value of the game. I will elaborate the idea in the following paragraphs.Consider how to add an element
$x_1$ to the left of the reduced sequence$b_1 > \dots > b_i < \dots < b_n$ . First, if$x_1 > b_1$ , nothing should be done except for adding the element$x_1$ directly to the left. If$x_1 \leq b_1$ , the sequence will be reduced further by replacing$b_1$ ,$b_2$ with$x_3 = x_1 - b_1 + b_2$ . And the so on process is repeated on$x_2, b_3, b_4, \dots, b_i$ . We can see that$x_j$ is of form$x_1 - b_1 + b_2 + \dots - b_{2j - 1} + b_{2j}$ and$x_j$ is compared with$b_{2j + 1}$ . The check turns out to be$(x_1 - b_1) + (b_2 - b_3) + \dots + (b_{2j} - b_{2j + 1}) > 0$ . As$b_{2k} > b_{2k + 1}$ always holds, we can do binary search to find the point where we have to stop.Now we turn to the most involved part. For a reduced sequence
$b_1 > \dots > b_i < \dots < b_n$ , we need to know the value of the game with the removal of a prefix. We further divide the reduced sequence into two chains: the downward chain$b_1, b_2, \dots, b_i$ and the upward chain$b_i, \dots, b_n$ . For the downward chain, we build a binary search tree of intervals$[b_{j + 1}, b_j)$ , and for each intervals we store the count of elements in the upward chain lying in its interval. By doing so, we can compute the game value with a part of downward chain$b_j, \dots, b_i$ and the upward chain$b_i, \dots, b_n$ . We can see that during the computation of the game value, the upward chain is naturally divided into two parts: the part in$[b_i, b_j]$ and the part in$(b_j, \infty)$ . The former part can be queried on the search tree, while the later part can be easily computed by binary search on the upward chain.To conclude, setting
$b = O(\sqrt{n})$ yields to$O((n + q) \sqrt{n} \log n)$ .