给定 (n),求长为 (2n) 的 (0) 到 (2n-1) 的排列 (p) 的个数,满足 (n^2le i^2+p_i^2le 4n^2)((0le ile 2n-1)),(1le nle 250)。
这题调了我三天,基本被抬走了…… AC 的时候血压骤降。
解析
把题目中的条件转换成几何形式,即 ((i,p_i)) 在内半径为 (n),外半径 (2n) 的圆环内。如图给出了一个 (n=2),(p=left<2,3,0,1 ight>) 的例子:
考虑没有内圆时的做法,即存在一个序列 (r_i),要求 (p) 满足 (r_ige p_i)。这是一个平凡的问题,即将 (r) 升序排序,第 (i) 位的选择数就是 (r_i+1-i)(每一位初始有 (r_i+1) 种选择,而有 (i) 种被占掉了,因为排序后之前的选择一定都被这一位包含),即答案就是 (prodlimits_{i=0}^{2n-1}(r_i+1-i))。
有内圆怎么做呢?设内圆产生的下界为 (l_i),先考虑将 ([l_ile xle r_i]) 类似的条件转换成 ([xle r_i]-[xle l_i-1]),接下来是一步经典的容斥转换:设 (f(k)) 为选 (k) 个数选择 (l_i) 为上界的方案数,则最终答案为:
考虑 dp 求解 (f(k)),即令 (f_{i,j}) 为对于前 (i) 个数,选取 (j) 个以 (l_x) 为上界的方案数。注意到方案数的关键在于排序,即计算多少个数影响了该决策,即小于自身。
当 (i<n) 时,以 (l_i) 为第一关键字,(r_i) 为第二关键字排序;当 (ige n) 时以 (r_i) 为关键字排序后,考虑以下转移(下文 (i) 代表原先下标,(i^prime) 代表排序后的下标):
当 (ige n) 时,即不存在 (l_i),此时造成影响的有:
- 小于自身的 (r_x),即 (x>i) 且 (xge n),设有 (cnt_1) 个;
- 可能选择的 (l_x),即 (j);
这种转移的贡献是 ((r_i-cnt_1-j+1)f_{i^prime-1}{j})。
考虑 (i<n),此时有两种决策:
- 选择 (l_i) 为上界,则造成影响的有:
- 满足 (r_x<l_i) 的 (r_x),和前面相同,也是 (cnt_1) 种贡献;
- 满足 (x>i) 的 (l_x),注意此时的贡献数是 (j-1),因为已经钦定了一个位置选择 (l_x) 为上界。
此时贡献是 ((l_i-cnt_1-j+2)f_{i^prime-1,j-1})(注意代码里还是 +1,因为下标不同)。
- 选择 (r_i) 为上界,类似的有:
- 满足 (x>i) 的 (r_x),注意这不仅包括了 (xge n) 的 (n) 个贡献((r_i) 单调),还有满足 (i<x<n) 且取 (r_x) 的情况。则后者的贡献是总数 (n-1-i) 减去已经除去的 (j) 种,两类相加为 (2n-1-i-j)。(代码中用
lc
代替了后者贡献中的总数) - 满足 (l_x<r_i) 的 (x),注意到这里有一个关键性质:所有的 (l_x) 都小于 (r_i),因为 (r_ige r_n=leftlfloorsqrt{3n^2} ight floorge sqrt{n^2}ge l_i)。所以这一部分的贡献与钦定的 (l_i) 总数有关,设其为 (k)。
- 满足 (x>i) 的 (r_x),注意这不仅包括了 (xge n) 的 (n) 个贡献((r_i) 单调),还有满足 (i<x<n) 且取 (r_x) 的情况。则后者的贡献是总数 (n-1-i) 减去已经除去的 (j) 种,两类相加为 (2n-1-i-j)。(代码中用
此时贡献是 ((r_i-2n+i+j-k+2)f_{i^prime-1,j}),若用 (lc) 表示则为 ((r_i-lc-k+j+1)f_{i^prime-1,j})。
则 (f(k)=f_{2n, k}),最终整体统计答案即可。每次指定 (k) 进行 dp 复杂度 (mathcal{O}(n^2)),总共 (mathcal{O}(n^3)),可以通过。
注意事项
- 将 ([lle xle r]) 转换成 ([xle r] - [xle l-1]) 别忘了 -1;
- 循环边界,循环边界,循环边界!怎么强调都不为过!(f_{x,k}) 算了吗?(f(0)) 算了吗?
- dp 数组清空了吗?dp 初始值设了吗?
- dp 顺序的排序,注意关键字的顺序和大小关系。
- 有没有输出负数?