非常好 Counting,使我滨州发光旋转。
2m>n 显然无解,判掉。
首先考虑,对于一个 >m 的数,如果它填到了左边,那么它所对应的位置就没有限制了。所以考虑在 >m 的数中选择 m 个,有序地填到左边,右边 n−m 个位置就有 m 个没有限制,剩下 n−2m 个位置有限制。
如果我们设 fi,j 为一个长为 i+j 的序列,前面 i 个位置没有限制,后面 j 个位置有限制的方案数,则答案为 m!(mn−m)fm,n−2m,现在我们的目标就变为快速求出 fi,j。
考虑推导出递推式。按照传统错排问题的思路,考虑填一个有限制的位置对应的数。考虑两种情况:
- 其对应的数填到了一个无限制的位置,则这个有限制的位置变为无限制的位置,被填到的那个位置被移除,相当于少了一个有限制的位置,无限制的位置个数不变,方案数为 i×fi,j−1。
- 其对应的数填到了另外一个有限制的位置,则这个有限制的位置变为无限制的位置,被填到的那个位置被移除,相当于少了两个有限制的位置,无限制的个数多了一个,方案数为 (j−1)fi+1,j−2。
于是可以 O(n2) 预处理 fi,j。
尝试填一个无限制的位置对应的数得到另一个递推式,考虑两种情况:
- 其对应的数就填在这个位置,则不产生任何贡献,方案数为 fi−1,j。
- 钦定其对应的数不能填在这个位置,这个无限制的位置变为有限制的位置,方案数为 fi−1,j+1。
整合一下得到两个递推式:
fi,j=i×fi,j−1+(j−1)fi+1,j−2fi,j=fi−1,j+fi−1,j+1
将第二个递推式代入第一个递推式的 fi+1,j−2 中,得到:
fi,j=i×fi,j−1+(j−1)(fi,j−2+fi,j−1)fi,j=(j−1)fi,j−2+(i+j−1)fi,j−1fi,j+2=(j+1)×fi,j+(i+j+1)fi,j+1
所以如果知道了 fi,j,fi,j+1 可以 O(1) 求出 fi,j+2。根据最开始的第二个递推式,有:
fi+1,j=fi,j+fi,j+1fi+1,j+1=fi,j+1+fi,j+2
将 fi,j+2 代入,得:
fi+1,j+1=(j+1)×fi,j+(i+j+2)fi,j+1
所以如果知道了 fi,j,fi,j+1 可以 O(1) 求出 fi+1,j,fi+1,j+1。
我们也可以手动解方程回推,知道 fi,j,fi,j+1 可以 O(1) 求出 fi,j−1 以及 fi−1,j,fi−1,j+1:
fi−1,j=i(i+j+1)fi,j−fi,j+1fi−1,j+1=ifi,j+1−(j+1)fi,jfi,j−1=jfi,j+1−(i+j)fi,j
综上所述,我们可以维护 (fi,j,fi,j+1),并在 O(1) 的时间复杂度内支持 i→i±1,j→j±1 四种操作。于是将询问离线下来,上莫队即可,时间复杂度为 O(Tn)。代码在这里。