题意:给出长度为2n的序列,问有多少种分割方案,使得每个子段长度为偶数且众数出现次数不大于长度的一半
首先转化一下,考虑众数出现次数大于长度一半的序列,我们用这个众数去找到这样的序列(注意到一个不合法序列不会被重复统计)
于是可以枚举每个数字(设为col),把序列中等于col的位置设为1,其他设为-1,这样前缀和会形成如下折线:
那么,右端点为i的不合法区间,它的左端点就是红线以下的位置:
但是这样的位置是很多不连续段,不好直接统计,于是可以考虑上图的j位置,那么i对应的不合法左端点集合,就是j对应的集合(可能需要并上[i, j]这一段)
这样,就可以从i向j连边,在图上进行dp
中间有一些细节和证明如下(有些加一或减一在此忽略了,这是大概思路):
1.边的条数为O(n) :注意到对于每种颜色col,边(i, j)满足i或j位置上为col,这样,点对(i, j)只有O(col出现次数)条,总共就有O(n)条
2.每个位置需要拆成对应每个颜色的点:即对于每个颜色col,如果位置pos出现在某条边内,就给他新建一个点(由1可知,最后只会拆出来O(n)个点)
3.如何快速找到i对应的j:注意到这个过程类似于括号匹配,可以通过不断删除相邻的1,-1来实现,具体来说,对于每个颜色col,用一个双向链表,从前往后,从后往前每个颜色为col的位置分别扫一遍,不断删除,并找到边(i,j),最后撤销就行,总复杂度O(n)
总的时间复杂度O(n)/O(nlogn)