A
把所有形如(a,ka)的路径提出来,共有O(nlogn)条路径,后面将这种路径称为限制。
考虑答案路径如果要不合法,那么必然覆盖了至少一条完整的限制。
考虑覆盖限制(u,v)的路径(a,b),设dfnx表示x的dfs序,endx表示x的子树中最大的dfs序,不妨设dfnu<dfnv,dfna<dfnb。
- 当u是v的祖先的时候,考虑g是离u最近的路径(u,v)上的点,要么dfna<dfng,dfnv≤dfnb≤endv,要么dfnv≤dfna≤endv,dfnb>endg。
- 当u不是v的祖先的时候,显然dfnu≤dfna≤endu,dfnv≤dfnb≤endv。
第一种情况构成了2个矩形,第二种情况构成了1个矩形。
最终我们只要求出所有矩形的并然后取个反即可,扫描线+线段树,总复杂度O(nlog2n)。
B
观察一下可以发现,如果将同一行与同一列的1用边连起来,一种方案可以拆成很多个环,从这个方面入手。
设fn表示n×n矩阵的答案,我们枚举第一行所在环的大小,那么有递推式: f_n = \sum_{i = 2}^{n}A_i\cdot \binom{n}{i}\cdot \binom{n - 1}{i - 1}\cdot f_{n - i}
其中A_i表示i\times i的矩阵只有一个环的方案数,\binom{n}{i}表示选出i列,\binom{n-1}{i-1}表示选出除了第1行的剩下的i-1行。
先给出结论:A_n = \frac{n!(n-1)!}{2},那么式子化成: f_n = \sum_{i = 2}^{n}\frac{i!(i-1)!}{2}\cdot \binom{n}{i}\cdot \binom{n - 1}{i - 1}\cdot f_{n - i}
将组合数拆开化简,得到: f_n = \frac{n!(n-1)!}{2}\sum_{i = 2}^{n}\frac{f_{n-i}}{((n-i)!)^2}
设g_n = \frac{f_n}{(n!)^2},那么有: g_n = \frac{1}{2n}\sum_{i = 2}^{n}g_{n - i}
维护前缀和即可,复杂度O(n)。
现在考虑怎么证明A_n = \frac{n!(n-1)!}{2}。
先n!每行每列放一个1,设p_i表示第i行1的列编号。在p_1列放第二个1 有n-1种方案,假设第二个1行号为q_i,那么接下来考虑p_{q_i}列,这列第二个1有n-2 种放法,因为不能在此时返回第一行,再加上已有2个1的行不能再放1。接下来就是n-3...。除以二是因为这个过程的逆过程也被计算过了。
C
一眼费用流裸题,但是数据范围有点大,考虑动态维护流量。
设当前加入的点编号为x,因为深度是O(\log n)的,因此我们可以枚举x和x要到的点的LCA,对于当前LCA设为g,我们需要求出g往子树中走最小的代价使得可以流到一个还有剩余容量的点,设为down_g。注意子树中行走的代价可以根据每条边的流量正负来确定,因此要维护每条边的流量,其实就是手动维护网路流。我们需要求出down_g+cost(x\rightarrow g)中代价最小的那个,然后暴力维护每条边的流量即可。
复杂度O(n\log n)。