主要是类似第一篇题解的实现。
这个解法在 check 的时候利用了这样的性质:若左/右侧散块中某个数字 x 是所有 x 中的第 i 个,则只需要判断第 i±ans 个 x 是否存在且在询问区间内,就可以判断 x 出现次数是否 >ans,进而可以暴力更新 ans。
但是注意到一个问题。假设左侧散块中 ∃ai=aj=x(i<j),则容易发现同一个 ans 的条件对 j 比对 i 要更严格,可能出现“先在 i 处更新 ans 后 j 处就更新不了,反过来先在 j 处更新答案后 i 处也能更新”这样的情况。
或者说随着 ans 增加,判定条件会越来越严,所以我先查验条件严格的位置才能避免漏掉条件;尽管这样似乎会出现左右两侧更新的顺序问题,但是我先假设可以忽略这一点。
所以我这么写能通过:
for(int i=R[ix[l]];i>=l;i--)
for(int i=L[ix[r]];i<=r;i++)
而用其他的顺序遍历都会出现 WA。
但是题解看起来压根没有考虑这一点,并且我随意改变遍历顺序看起来都会获得 AC。
所以是我某些地方写蠢了导致的,还是说我漏了某些类似“任意顺序遍历都可以,前面的情况不会出现”的证明?
代码放二楼。