关于一些实现细节
查看原帖
关于一些实现细节
678087
fangzichang楼主2024/9/25 09:50

主要是类似第一篇题解的实现。
这个解法在 check 的时候利用了这样的性质:若左/右侧散块中某个数字 xx 是所有 xx 中的第 ii 个,则只需要判断第 i±ansi\pm ansxx 是否存在且在询问区间内,就可以判断 xx 出现次数是否 >ans>ans,进而可以暴力更新 ansans
但是注意到一个问题。假设左侧散块中 ai=aj=x(i<j)\exists a_i=a_j=x(i<j),则容易发现同一个 ansans 的条件对 jj 比对 ii 要更严格,可能出现“先在 ii 处更新 ansansjj 处就更新不了,反过来先在 jj 处更新答案后 ii 处也能更新”这样的情况。
或者说随着 ansans 增加,判定条件会越来越严,所以我先查验条件严格的位置才能避免漏掉条件;尽管这样似乎会出现左右两侧更新的顺序问题,但是我先假设可以忽略这一点。
所以我这么写能通过:

for(int i=R[ix[l]];i>=l;i--)
   //...
for(int i=L[ix[r]];i<=r;i++)
   //...

而用其他的顺序遍历都会出现 WA。
但是题解看起来压根没有考虑这一点,并且我随意改变遍历顺序看起来都会获得 AC。
所以是我某些地方写蠢了导致的,还是说我漏了某些类似“任意顺序遍历都可以,前面的情况不会出现”的证明?
代码放二楼。

2024/9/25 09:50
加载中...