CF1168 A~C
CF Round 562
A Increasing by Modulo
这个我们操作 k 次就是至多给一个数字 + k ,所以直接二分一下 k 就好了。
cpp
1 |
|
B Good Triple
开始看了好久硬是不知道怎么做。。后来 zzh 说了一下,考虑一个位置左右第一个相等的位置其实期望情况下很近啊?然后想想,貌似卡不掉。。于是直接拿最近的位置暴力就行了。原理是一个显然的贪心,如果以一个位置坐中心可以更近地得到两边相同就肯定不会去找远的。
cpp
1 |
|
C And Reachability
同时把一个数字看成 它所代表的二进制代表的集合。
首先,如果 A[x] 与 A[y] 有交,显然可以一步到达。
否则,我们希望通过中间的数字使得 A[x] 变得和 A[y] 有交。
然后考虑这个过程在做什么,在从左往右走,如果和这个数字有交,就可以将当前数变成这个数字。但是我们可以感性理解一下拿和不拿这两种状态是可以任意决定的,所以其实你到达这里之后当前的数字就可以或上这个数。
也就是说,当我们到达一个数,如果和这个数有交,就把当前数字变成和它的或,看到达 y−1 时是否与 A[y] 有交就行了。
怎么优化这个过程?我们考虑在线段树上处理,对于每个线段树上的节点维护一下,如果某个位是 1 到达这个节点并离开这个节点时会 或 上什么东西,因为或运算满足结合律。于是就可以 O(nlog2n) 解决问题。
cpp
1 |
|