能使用莫队算法的条件是:
已知
[l,r]
的答案,能在O(1)
(或O(logn)
等较低的时间复杂度)的时间内求得[l+1,r]
与[l,r-1]
的答案 ——hzwer
那么我们观察这道题,假设一个区间[l,r]
内有m
只相同颜色的袜子 怎么觉得好恶心…,那么满足条件的取法有$C^2_m$种
而$C^2_m=\frac{m(m-1)}{2}$
整理一下,得$2C^2_m=m^2-m$
现在假设这个区间[l,r]
里有两种颜色的袜子,分别有a
和b
只,那么取法*2
共有$a^2+b^2-a-b$种(把这数放在分子上看起来太小,所以就直接换成取法*2
了)
三种颜色的取法*2
就是$a^2+b^2+c^2-a-b-c$种,发现这些式子对于某种颜色只有一只时也同样成立
所以得到取法总数*2
为$\sum_{i=1}^{colors}=colortot[i]^2-colortot[i]$(colors是区间内颜色的数目,colortot是每种颜色的袜子数),注意到后面那一坨的和就是区间里所有袜子的数
所以得到取法种数*2
即为$\sum_{i=1}^{colors}-(r-l+1)=colortot[i]^2-(r-l+1)$
这样就得出了计算区间[l,r]
内取法的方法,可以考虑上莫队了
分为$\sqrt{n}$块,对其进行排序,目标是使所有左端点在一个块内的询问的右端点是递增的,举个栗子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16n=6 m=15
1 2
1 3
1 4
1 5
1 6
1 7
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
分块大小为每块2个,排序后变成了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
171 2
2 3
1 3
2 4
1 4
1 5
2 5
2 6
1 6
1 7
---以上为第一块,右端点为递增的
3 4
4 5
3 5
4 6
3 6
---第二块
这样的话转移时就能省很多时间
初始时区间为[1,0]
,然后依次向每个询问进行转移,依据上面的公式,只需要维护一个变量表示当前区间内每种颜色数量的平方和,这个变量减掉区间内元素个数就是答案
分母就不用多说了吧,就是$C^2_{r-l+1}=\frac{(r-l+1)(r-l)}{2}$,发现分母分子都有$/2$,直接扔掉,然后用gcd
化简一下就是答案
1 | program bzoj_2038; |