题目大意:
现在要对一个数组执行q次指令,指令有两种类型,分别为”1 x”和”2 x k s”,前一种是向数组中加一个数x,后一种是查询数组中是否存在这样一个v,使得v满足$k \mid \gcd(x, v) , x + v < s$, 若不存在,输出-1,否则输出满足条件的v中值最大的那个。
解题思路:
首先观察条件,很明显的当$x \mod k \neq 0$时,答案是-1, 当$s - x \leq 0$时,答案是-1。
对于其余情况,因为插入的数在1 ~ $10^5$间,而且用到这个数只要它出现过就可以,与它出现的次数无关。所以我们可以用桶排序的思想,用一个数组标记这个数字是否出现过。对于给出的查询,我们只需从k开始找,到$s - x$为止,每次加k,看枚举的数是否出现过,同时更新记录最大值就OK了。
然而这样会T。因为当k = 1时,这样做就和暴力无差了。那么我们怎么办呢?k = 1,就是从1 ~ $s - x$中找出一个数使得这个数与x的异或结果最大。没错,就是区间异或最大值!字典树!
前两篇讲的是没有最大值限制的查询,这里有了限制也很简单,我们把之前用的这一位是0|1的pre数组改为到此结点时最小值是多少,然后从根结点开始往下搜索,最后返回叶子结点存的值就好了。为什么这样是对的?因为我们往下找的时候是根据异或结果找的,找到叶子结点时当然就是最大的了。对了,往下找的时候要多加一句判断——是否下面的最小值不大于我们的限制。
Mycode:
1 |
|