这是 NOI 的一个非常非常好的组合计数题。
先考虑这么一个问题: 有一个长度为 (n) 的排列,它的前 (m) 位给定,问有多少种确定剩下 ((n-m)) 位的方案使得整个排列是好的。
结论:一个长度为 (n) 的排列是「好」的,当且仅当不存在 (1le i< j< k le n, a_i>a_j>a_k)。
证明:咕咕咕
首先已确定部分如果已经存在以上的不合法情况,或者不管怎么填都不可能合法,那么答案为 (0)。
观察已确定的部分的最大值 (x),那么容易发现剩下的数中小于 (x) 的应该按升序排。于是想到先处理大于 (x) 的部分,然后再把小于 (x) 的插进去。
- 对于大于 (x) 的部分,可以看作一个长度为 (n-x) 的好的排列的问题;
- 然后插入小于 (x) 的数,注意到小于 (x) 的数之前不能有大于 (x) 的部分的逆序对。
于是发现,对于大于 (x) 的部分的一种填法,接下来插入小于 (x) 的数的方案数只与 第一个 逆序对结束点 的位置 有关。
考虑 DP 解决。(f_{i,j}) 表示长度为 (i) 的「好」排列中,有多少个的第一个 逆序对结束点 在 (j)。(特别地,如果不存在逆序对,那么规定第一个逆序对结束点为 (n+1))
可以得到 (f_{i,j}=sum_{k=j-1}^{i}f_{i-1,k}),边界 (f_{i,1}=0,f_{1,2}=1)。(考虑枚举最小值的位置即得转移方程)
很明显 (f_{i,j}=f_{i,j+1}+f_{i-1,j-1})。至此,我们所做的 (Theta (n^2)) 的。要看看能不能优化。
打表出来发现它跟卡特兰数有关,于是我们试着往卡特兰数的方向去靠。
于是想到 (f_{i,j}) 相当于从 ((1,2)) 走到 ((i,j)),每一步只能往下或者往右上走,且不能走到直线 (y=1) 上的方案数。
这又相当于从 ((0,0)) 走到 ((2i-j,j-2)),每一步只能往右下或者右上走,且不能走到直线 (y=-1) 上的方案数。这是经典问题,答案为
({2i-jchoose i-1}-{2i-jchoose i}),你可以参考 这里。
那么答案为 (sum_{j=2}^{n-x+1}left[{2(n-x)-jchoose n-x-1}-{2(n-x)-jchoose n-x} ight]{j-1+x-mchoose x-m})
还可以再化简!
(sum_{j=2}^{n-x+1}left[{2(n-x)-jchoose n-x-1}-{2(n-x)-jchoose n-x} ight]{j-1+x-mchoose x-m}\ =sum_{j=2}^{n-x+1}{2(n-x)-jchoose n-x-1}{j-1+x-mchoose x-m}-sum_{j=2}^{n-x}{2(n-x)-jchoose n-x}{j-1+x-mchoose x-m}\ =[{2n-m-xchoose n-m}-{2n-2x-1choose n-x-1}]-[{2n-m-xchoose n-m+1}-{2n-2x-1choose n-x}]\ ={2n-m-xchoose n-m}-{2n-m-xchoose n-m+1} )
现在我们来考虑原问题。
由于我不想算字典序严格大于 (q) 的「好」排列个数,所以容斥一下,答案就等于好的排列总数减去字典序不大于 (q) 的「好」排列个数。
从前往后考虑 前 ((i-1)) 位与 (q) 的前 ((i-1)) 位相同 但 第 (i) 位比 (q_i) 小 且 符合条件 的排列有多少个。根据刚才得到的式子,我们发现有解时答案只和 (n,m,x) 有关,所以
-
(q_i< max_{j=1}^{i-1}q_j) 时,
- 如果在 ([1,q_i)) 内都填过了,那这一位没有贡献;
- 如果还有没填过的,那容易发现,这一位必须填没填过的当中最小的一个数,并且因为连 (q_i) 都填不了,后面的答案都是 (0) 了,只能 break 掉;
-
(q_i> max_{j=1}^{i-1}q_j) 时,如果想选 ([1,max_{j=1}^{i-1}q_j)) 内的东西,一样的只能选最小的那个,但这时不用 break 掉;否则暴力往上推即可,这个一共只会推 (O(n)) 次。
最后要算上 (q) 自己的好坏。
只要维护一个 (operatorname{mex}),不用树状数组,时空复杂度 (O(n))。