转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:给出一个序列,mex{}表示集合中没有出现的最小的自然数。然后 求sigma(mex (i , j)).
比赛的时候,被老大秒了。。。太可怕了。。。
做法:考虑左端点固定时的所有区间的mex值,这个序列是一个非递减了。。。首先要明白。
初始就是求出mex[i]表示 mex(1 , i),对于每一个左端点,就是一个区间求和。
现在需要考虑的是左端点的改变对于序列的影响。。。
即左端点从i -> i + 1,mex[j]的改变。。。。即删去ai对于序列的影响。
如果 a[j] = a[i] 且 j > i ,不存在a[k] = a[i] j > k > i。即a[i]下一次出现的位置 。
根据mex的定义,我们知道 mex[k]不会改变, k >= j。因为删掉的ai还是存在于序列当中,所以不受影响。
之后需要考虑的是i +1 到 j - 1这段区间的mex值。。。删去了ai之后,使得原先mex值大于ai的,都会更新成ai。
很好理解。。。因为是没有出现的最小的,ai更小。。。
之前说过这是一个非递减的序列,所以原先mex值大于ai的也是一段连续的区间,所以我们可以找到最靠左的位置 r,使得mex[r] > a[i]。那么r 到 j - 1这段区间的mex值便 会更新为a[i]。
所以全部搞定。。。用线段树维护一下mex序列,区间更新,区间求和,然后一个查找就可以了。。。
下面的代码是我把老大的code中线段树部分重写后的。。
#include
#include
#include