Cdeforces Round #719 (Div. 3) 题解(A-E)

A. Do Not Be Distracted!

用一个数组保存一道题上一次出现的下标。枚举位置,如果存在位置(i),使得(s_i)非首次出现且上一次出现的下标不是(i-1)NO,反之YES

B. Ordinary Numbers

满足条件的数其实非常少,且容易生成,所以直接预处理出所有满足条件的数,再排个序。

对于询问直接二分回答就可以了。

C. Not Adjacent Matrix

记结果矩阵为(M)。令(M(i, j) = i + (j-1) * n),这样水平方向不会有冲突。

现在只需要消除竖直方向的冲突,将第(i)行循环右移(i-1)位即可。

D. Same Differences

(a_j - a_i = j - i Leftrightarrow a_j - j = a_i - i),然后就是扫一遍的事情了。

E. Arranging The Sheep

假设有一个中心点(c),将所有羊分为左和右两部分,左边的羊右移,往右边的羊左移。

枚举(c)的所有可能值,计算出每种情况的代价,其中的最小值既是答案。

(c)的可能值有(n)种,每次如果暴力算代价的话,就会超时。但是,其实有(O(1))的转移。

假设上一次的中心点为(c),现在的中心点为(c+1),记左边有(L)只羊,右边有(R)只羊,代价为(Cost)

  • 如果(s_{c+1}=*),那么(Cost)不变,(L=L+1)(R=R-1)
  • 如果(s_{c+1}=.),那么(L,R)不变,(Cost=Cost+L-R)

F1. Guess the K-th Zero (Easy version)

直接二分。

F2. Guess the K-th Zero (Hard version)

做法1

使用类似权值线段树或者二叉搜索树求第K大的策略可以卡过去,就是每次询问([l, mid]),判断下一步往那个子树走。然后询问过的区间后续其实可以不花费询问次数就得到答案的。

下面证明一下这样子不会花费超过限制的询问次数。

对于(n = 2 imes 10^5),把树建出来后,树的树高不会超过(18)

对于前(14)层,每个节点至多询问1次,这一部分至多(2^{14})次询问。

对于(15)(18)层,其中的每一层,每个询问至多经过一次,所以这一部分至多(4t)次询问。

总的至多(2^{14} + 4t)次询问,符合要求。

做法2

然后看讨论区学到了另外一种做法就是分块做。

先将序列以(8)的大小分块,然后直接(frac{n}{8})次询问搞出块级别的前缀和。

之后的每一个询问,就可以不花费询问次数,二分找到目标位置所在的块,再通过3次询问找到目标位置。

询问完之后有单点加操作,搞个线段树之类的数据结构维护区间和或者前缀和就完事了。

询问的次数为(3T + frac{n}{8}),符合要求。

G. To Go Or Not To Go?

首先可以不考虑传送门,两次BFS分别跑出从起点以及从重点跑到((x, y))的代价。因为移动的代价恒为(w),所以每个位置至多经过一次,这一部分的复杂度为(O(nm))。且不使用传送门的最小代价也能计算得到。

因为通过传送门可以到达其他任意传送门,所以传送门也至多使用一次。此外,由于使用传送门的代价是两传送门权值相加,所以可以令入口传送门的代价为起点到它的代价加上入口传送门权值,出口传送门的代价为终点到它的代价加上出口传送门权值,两者的最小值相加即为使用传送门的最小代价。

原文地址:https://www.cnblogs.com/zengzk/p/14734709.html