CF Round 1046(#2135) 总结
A
可以 DP,用 vector 存下这个数出现的位置。
B
考虑移动到无限远处,如果移到左下角,容易发现离的最近的点就是离 \((-10^9,-10^9)\) 最近的点。这样就能确定一条直线(确定 \(x+y\))。
同理移动到左上角又确定一条直线(确定 \(x-y\))。
需要 8 次询问。
C
首先把边双找出来,容易发现不同边双是不会影响的。
考虑一个边双内,题目的限制形如每个环的异或和都为 \(0\),发现这其实可以推出边双内所有点的权值相等。所以就做完了。
D1 & D2
考虑到问一个长为 \(n\) 的全是 \(k\) 的序列,可以得到 \(\lceil\dfrac n {w/k}\rceil\),这大概有 \(O(\sqrt n)\) 种取值。
考虑按 \(B=\sqrt {10^5}\) 分块,可以问 \(k=B\) 实现,对于 \(w<B\) 可以问 \(10^5\) 个 1;否则可以问 \(\lfloor \dfrac w B\rfloor B,1,\lfloor \dfrac w B\rfloor B,2,\lfloor \dfrac w B\rfloor B,3,\dots\),一直问到 \(B\)。
这可以通过 D1。
考虑 D2,可以继续优化,其实每块的长度可以不固定,问一个 \(k\) 以后,可以知道 \(w\) 在区间 \([L,R]\) 内,只需要问 \(L,1,L,2,L,3\dots\),一直问到 \(L\) 即可。而对于 \(w<k\) 的情况,同样可以问 \(k^2\) 个 \(1\)。精细实现即可。
E1 & E2
把 \(0\) 看做 \(-1\),求出前缀和,等价于 \(\min s +\max s=s_n\)。
考虑格路计数,然后反射容斥。做出 E1 后还要优化。
F
考虑怎么比较 \(f(x),f(y)\),考虑比较它们的指数 \(\prod f(a_i),\prod f(b_i)\)。
把 \(a_i,b_i\) 都按 \(f(a_i),f(b_i)\) 从大到小排序,我们找到第一个不等的位置,\(f(x),f(y)\) 的大小就是 \(f(a_i),f(b_i)\) 的大小。这是因为若 \(f(a_i)<f(b_i)\) 则它们至少差一个 \(x\) 数量级,那么后面的位无论乘都不会比 \(f(a_i)\) 大。
那么现在只需考虑求出 \(f(x)\) 的排名,然后比较两个 \(f\) 就是按上述方式比较排名序列。
由于一个点的 \(f\) 大于其子树内的。考虑按照拓扑序把 \(x\) 丢进堆里,每次取出最小的 \(f(x)\),维护一个当前排名,若 \(f(x)>f(lst)\) 则将排名加一。然后更新其父亲的 \(f\),发现其父亲的 \(f\) 就是继承其左儿子的排名序列,然后再插入右儿子的排名。
考虑快速比较两个排名序列,把序列中所有点插到线段树上,维护节点内的哈希值,比较排名序列就可以线段树上二分。而继承左儿子的排名序列就是类似可持久化操作。复杂度 \(O(n\log ^2n)\)。事实上直接用 vector 维护排名序列,然后把序列中相同排名并起来,修改和比较都暴力做,这样是卡不掉的。
