test20191004

闲扯

这次的考试题感觉也不是很难,但是比较考思维。还有我 \(hash\) 感觉跟没学过一样,这次顺便也学了下吧。

\(T1\)

Solution

我们将题目简化一下,相当于是求下面的式子:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} (g(a_i\ xor\ b_j)==2) \]

其中 \(g(x)\) 的定义是数 \(x\) 在二进制表示下 \(1\) 的个数。
一个简单粗暴的方法是直接枚举 \(i,j\) ,然后暴力判断 \(g(a_i\ xor\ b_i)\)
这样做的时间复杂度是 \(O(n^2\log max\_val)\) ,可以通过 \(60\%\) 的数据。
考虑优化。
我们可以发现,我们相当于对每一个 \(a_i\) 找两个数 \(x,y\) ,找出等于 \(a_i\ xor\ 2^x\ xor\ 2^y\)\(b_j\) 的个数。即:

\[a_i\ xor\ 2^x\ xor\ 2^y=b_j \]

我们写一个 \(hash\) 表来存对于每一个 \(a_i\) ,我们得到的值,然后对于每一个 \(b_i\) ,查询经过一系列操作得到的他的个数即可。
这样做的时间复杂度是 \(O(n\log^2 max\_val)\) ,可以通过 \(80\%\) 的数据。
继续优化。
我们对前面的式子进行一下变化,得到下面的式子:

\[a_i\ xor\ 2^x=b_j\ xor\ 2^y \]

这样,我们只需要对两边都枚举一个数,然后查找中途相遇的个数即可。
但是需要注意的有两点:

  1. 对于相同的 \(a_i,b_j\) 我们需要将它们减去。
  2. 对于最后的答案,我们需要除以 \(2\) 。(有重复计算)

时间复杂度: \(O(n\log n)\)

\(T2\)

我们不需要直接维护有没有通路,只需要看有没有一条链,使得左右边界连接起来了。
这个我们可以用并查集维护。
因为最左边和最右边是可以连通的,所以我们再可以复制一份,放到另一边,随便乱搞一下就行。

\(T3\)

考虑 \(DP\)
我们设 \(dp_{i,j}\) 表示考虑前 \(i\) 位,其中 \(\sum\limits_{k=1}^{i} a_k\cdot x_k\leq j \leq \sum\limits_{k=1}^{i} b_k\cdot x_k\)
转移时,我们有如下转移方程:

\[dp_{i,j}=\min(dp_{i-1,j},\min\limits_{j-b_i\leq x\leq j-a_i}(dp_{i-1,x})+c_i) \]

这就是一个单调队列优化 \(DP\) 的板子题了。

posted @ 2019-10-04 20:32  TheShadow  阅读(95)  评论(0编辑  收藏  举报