交互题 笔记
yyy loves Math VI
记录两个数x, cnt,初始x = −1, cnt = 0。
• 碰到一个数a时:
• 若a = x,则cnt ← cnt + 1
• 否则:
• 若cnt = 0,则x ← a, cnt ← 1
• 否则cnt ← cnt − 1
• 最后的x就是答案。
US Open 2018 Train Tracking
记录\(f(i)\)表示区间[i,i+k-1]的最小值的下标的位置,显然f(i)具有单调性
第一次统计出\(f(\sqrt n \times j)\),第二次按段维护答案
单调队列优化
In this problem, we are asked to find all sliding-window minima in an array, for some fixed-length window. We are given two passes through the array. The catch is that we are given only O(√N) memory.
Let f(i) be the location of the smallest element in the range [i,i+K), breaking ties by smallest index. Observe that f(i)≤f(i+1) for each i. So if we compute f(0),f(B),f(2B),…,f(N) for some block size B in the first pass, this gives us some information which we may be able to use in the second pass to compute the remaining f(i)s.
Let's ignore the constraint on calls to set/get for now. If we let B=√N, then we can compute f(0),f(√N),…,f(N) in our first pass using only O(√N) memory and O(N√N) time. Now, in the second pass, observe that for any fixed array element i, there are only O(√N) windows for which the minimum could possibly be at position i.
This suggests the following algorithm for the second pass: read and ignore all elements with index less than f(0). Now maintain running minima for f(0),f(1),f(2),…,f(√N). Once we've read in the element with index f(√N), we know that we have computed the correct minima for the first √N windows. Output these, start maintaining minima for the next √N windows, and continue in the same fashion.
The memory usage of the second pass is also √N, as desired. Unfortunately, the time complexity of each pass is O(N√N). In particular, the above algorithm would use O(N√N) calls to set and get, which would exceed the given bound. To improve the time complexity, we can use a monotonic queue in each pass. In the first pass, for instance, the boundaries of the √N windows define 2√N subarrays, and for each subarray we can simply compute the minimum of the subarray and put that into the monotonic queue. The length of the monotonic queue therefore never exceeds O(√N), and we can compute the √N minima-locations in O(N) time. For the second pass, it suffices to observe that in each segment of the array (say, between f(i√N) and f((i+1)√N)) all but O(√N) of the array elements are in all √N windows of interest. This once again allows us to improve the pass to O(N) time will not exceeding O(√N) memory.
UR#4 元旦激光炮
每次查询三个数组中每个数组的k/3的位置的数
把最小的那个和它前面的所有数删掉
所以每次可以把k*2/3
最多31次可以把k变成2
然后每个数组询问前两个数找到最小值
寻找山峰
第一次在正中间竖切一刀
然后找到最大值 然后向两边各探索一个格子
如果是山峰=>end
否则在两边的比他大的那边一定有一个山峰
在那一边横着切
重复操作
第一次n次查询
第二次n/2次
第三次n/2次
第四次n/4次
...
n+n/2+n/2+n/4+n/4+n/8...=3n
每一次探索两个格子 一共2log次
一共4log次探索
CF727 C Guess the Array
查询a1+a2,a2+a3,a1+a3
把a1,a2,a3解出来
然后查询a1+ai得出ai
AIM Tech Round 4 B. Interactive Lowerbound
随机1000次找到比x小的最大的数
然后从这个数开始向后找1000个
找不到答案的概率是(1-1e3/1e5)^1000=4e-5
CF810 D Glad to see you
我们可以将(1~n)分成两份(1~mid)(mid+1~r),显然要猜的数肯定是在这两个区间内。
然后怎么判断我们可以找mid和mid+1两个数来判断,如果|mid-a|<=|mid+1-b|,那么显然要猜的数肯定是mid或者mid的左侧。如果|mid-a|>|mid+1-b|很显然要猜的数肯定是mid+1或者mid+1的右侧然后就是二分,根据题目的回答进行二分
CF862 D Mahmoud and Ehab and the binaru string
先查两次 0000..0, 100...0
然后可以确定第一位是0/1
假设第一位为0
我们要找一个1
每次把一半的位设成1
比如11111..100000..0
然后与000..000的答案配合
这样我们可以知道前一半的位置上是1的个数
如果是0个就在后一半查找
否则在前一半查找
log次
CF744 B Hongcow's Game
两种做法
- 整体二分
- 按位分类
按位分类的例子:
给n个数其中两个数出现了奇数次, 其他的数都出现偶数次
空间限制O(1) 可以从头到尾扫log次 找出这两个数
sol:
先扫一遍求出异或和
然后对于每一位 我们扫一遍找出这一位为0的数的异或和,这一位为1的数的异或和
然后如果两个不同的数在这一位上相同 那么肯定一个是0一个是总的异或和
如果在这一位上不同(一定存在这样的一位) 那么这两个异或和就是这两个数