2025.2.15 NOIP 模拟赛 T2
Descreption
对满足以下条件的 排列 计数:
- 长度为 \(n\) 且逆序对数恰好为 \(n\)。
答案对 \(10^9+7\) 取模。
\(\mathcal{O(n^2)}\) Solution
设 \(f_{i,j}\) 为长度为 \(i\) 的排列,逆序对数恰好为 \(j\) 的方案数。
假如已经计算出了长度为 \(i-1\) 的答案,现在考虑如何计算 \(i\) 的贡献。
考虑将 \(i\) 这个数字插入到某一处。显然现在 \(i\) 就是排列中最大的数字,那么如果它后面有 \(k\) 个数字,就会产生 \(k\) 个新逆序对。最少产生 \(0\) 个,最多产生 \(i-1\) 个。
那么有转移:\(f_{i,j}=\sum_{k=min(j-(i-1),0)}^j f_{i-1,k}\),前缀和优化可以做到 \(O(n^2)\)。
\(O(n \sqrt{n})\) Solution
由 $O(n^2) $ 做法拓展。
做一个题意转化:
- 有 \(n\) 个未知数 \(x_1,x_2,...x_n\),求 \(\sum x_i=n\) 且 \(x_i<i\) 的非负整数解个数。
正确性显然。
套路地考虑容斥,枚举使得 \(x_i\geq i\) 的 \(i\) 的集合 \(S\),那么 \(S\) 中的元素至少已经占据了 \(Sum(S)\) 个位置。
此时又有了一个子问题:求 \(\sum x_i=n-Sum(S)\) 的非负整数解个数。隔板法可解。
答案为:
若直接枚举集合 \(S\),效率未免太低。注意到若两个集合的元素总和与大小相同,则两个集合等价。
那么设另一个 dp:\(f_{i,j}\) 表示选择了 \(i\) 个数字,总和为 \(j\) 的集合数量。
注意到集合中的数字必须两两不同,那么集合大小不会超过 \(\sqrt{2n}\)。
接下来考虑转移。我们每次向集合中加入一个最小值,不妨钦定为 \(1\)。为了避免重复,我们先将原集合中所有数字加一,然后再加入。
但集合最小值可以不为 \(1\)。我们只需接着把新集合所有元素向上平移若干次即可。
得到转移:
- \(f_{i,j} \rightarrow f_{i+1,j+i+1}\);
- \(f_{i,j}\rightarrow f_{i,j+i}\)。
最终的答案化为:
代码很简单,懒得粘了。