首页 > 其他 > 详细

test20191004

时间:2019-10-04 20:53:57      阅读:81      评论:0      收藏:0      [点我收藏+]

闲扯

这次的考试题感觉也不是很难,但是比较考思维。还有我 \(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\) 的板子题了。

test20191004

原文:https://www.cnblogs.com/TheShadow/p/11623109.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!