Description
一个序列有2n2n2n个数,现在你要在这个序列中配得nnn个无序数对,使得每一对的两个数不同且每个数都在恰好111个对中。
请求出合法配对的方案数。注意(1,3)(2,4)(1,3)(2,4)(1,3)(2,4)与(2,4)(1,3)(2,4)(1,3)(2,4)(1,3)这两种配对方式是等价的。
请将答案对998244353998244353998244353取模。
n≤50000,ai≤105n≤50000,a_i≤10^5n≤50000,ai≤105
Solution
考虑dpdpdp。
如果按照整个序列去进行dpdpdp的话很难设计出合理的状态,所以考虑开桶dpdpdp,并令viv_ivi表示第iii个桶的大小。根据题意,每一个桶中的数不能进行匹配,不难得到状态设计与状态转移:
dpi,jdp_{i,j}dpi,j表示看到第iii个桶(即已经处理了111至iii号桶),还剩jjj个人未匹配的方案数。
状态转移如下:
dpi,j=∑k=0vi Cvik Aj−(vi−k)+kk dpi−1,j−(vi−k)+kdp_{i,j}=\sum_{k=0}^{v_i}\ C_{v_i}^k\ A_{j-(v_i-k)+k}^k\ dp_{i-1,j-(v_i-k)+k}dpi,j=∑k=0vi Cvik Aj−(vi−k)+kk dpi−1,j−(vi−k)+k
解释一下这个状态转移。kkk枚举的是在iii这个桶内与前面匹配掉的数的数量。CvikC_{v_i}^kCvik表示在第iii个桶中选择kkk个与前面进行匹配。由于看到第iii个桶还剩jjj个数未匹配,第iii个桶本身对“未匹配的量”的贡献是vi−kv_i-kvi−k,并且前面还要多留kkk个数与第iii个桶选中的数进行匹配,所以之前未匹配的数的数量应该是j−(vi−k)+kj-(v_i-k)+kj−(vi−k)+k。在这个里面选kkk个数与第iii个桶中选定的kkk进行匹配的方案数为Aj−(vi−k)+kkA_{j-(v_i-k)+k}^kAj−(vi−k)+kk。
每次暴力转移的时间复杂度是O(n3)O(n^3)O(n3)的,严重超时。我们先尝试将它优化到O(n2)O(n^2)O(n2)或类O(n2)O(n^2)O(n2)。
我们拆开状态转移式中的括号并观察:
dpi,j=∑k=0vi Cvik Aj−(vi−k)+k dpi−1,j−(vi−k)+kdp_{i,j}=\sum_{k=0}^{v_i}\ C_{v_i}^k\ A_{j-(v_i-k)+k}\ dp_{i-1,j-(v_i-k)+k}dpi,j=∑k=0vi Cvik Aj−(vi−k)+k dpi−1,j−(vi−k)+k
dpi,j=∑k=0vi Cvik Aj−vi+2k dpi−1,j−vi+2kdp_{i,j}=\sum_{k=0}^{v_i}\ C_{v_i}^k\ A_{j-v_i+2k}\ dp_{i-1,j-v_i+2k}dpi,j=∑k=0vi Cvik Aj−vi+2k dpi−1,j−vi+2k
考虑将dpi−1dp_{i-1}dpi−1翻转,就得到了一个卷积的形式。每次跑一遍NTTNTTNTT,时间复杂度优化到O(n2logn)O(n^2 \log n)O(n2logn)。
但是我们依然不满意。不难发现这个状态转移可以用cdq分治来优化,即分治NTT。每次我们递归左半边,跑一遍NTT处理左半边对右半边的贡献再往后边递归。由于递归的深度最大是logn\log nlogn的,所以卷积的次数为nlognn \log nnlogn次,总时间复杂度为O(nlog2n)O(n \log^2 n)O(nlog2n)。
NTT txdy!
Summary
在本题中,我们巧妙设计了dpdpdp状态,发现翻转后是一个卷积的形式,从而采用分治NTT将时间复杂度优化到了O(n2logn)O(n^2 \log n)O(n2logn)。
可以说这是一道比较套路的题,唯一较为灵活的就是dpdpdp的状态设计以及状态转移。分治NTT出来得比较自然,可惜蒟蒻(我)在想这题的时候并不会分治NTT,是在看了别人的题解之后才悟懂。
感觉这题放在ABC的F题是不是太过分了啊???
742

被折叠的 条评论
为什么被折叠?



