题目大意
给定\(n(1 \le n \le 10^5)\)个数\(a_i(0 \le a_i \le 2^{30})\)。有\(q(1 \le q \le 10^5)\)次询问:求\(l,r\)内任选两个数,它们与运算后的最小值是多少。 题目链接 ## 思路 一个重要性质 假设都是\(k\)位数,若要最小值那么只需要知道最小的\(k+1\)个数就可以了,结果由它们产生,证明如下: 采用数学归纳法, \(k=1\)时,那么所有数都是\(0,1\)其中一种,那么显然成立。选最小的两个数就可以成立。 假如\(n=k\)时成立,那么对于\(n=k+1\)时: * 所有数第\(k+1\)位均为\(1\),那么答案的这一位也是\(1\),所以就在剩下的位数中寻找最小的一部分数,此时子问题和\(n=k\)时一致,故结论成立。 * 至少有两个数第\(k+1\)位为\(0\),那么为了使得答案最小,肯定选择这一位为\(0\)的数,在低位寻找他们之间最小的一部分数,此时子问题和\(n=k\)时一致,故结论成立。 * 只有一个数第\(k+1\)位为\(0\),那么答案这一位也是\(1\),然后再在剩下的位数中寻找最小的数,此时子问题和\(n=k\)时一致。 等于说是分为了两部分,一部分是仅有的一个第\(k+1\)位为\(0\)的数,另一部分就是剩下的位数中寻找最小的一部分数,两部分加起来,就是\(k+2\)个 故假如\(n=k\)时成立,那么对于\(n=k+1\)时也成立。 证明完毕。
做法 那么剩下的就简单了,给定\(l,r\)可以用线段树维护区间最小的\(31\)个数,也可以用主席树连续查找\(k+1\)个第\(k+1\)小的数。然后求最小值
代码
1 |
|
- 本文作者: 水蓝络合物
- 本文链接: https://miku39393939.github.io/2022/04/18/cf1665E/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!