Qingyu✨的博客

博客

Easy Contest Tutorial

2020-07-10 16:04:03 By Qingyu✨

A

把所有形如(a,ka)的路径提出来,共有O(nlogn)条路径,后面将这种路径称为限制。

考虑答案路径如果要不合法,那么必然覆盖了至少一条完整的限制。

考虑覆盖限制(u,v)的路径(a,b),设dfnx表示xdfs序,endx表示x的子树中最大的dfs序,不妨设dfnu<dfnv,dfna<dfnb

  1. uv的祖先的时候,考虑g是离u最近的路径(u,v)上的点,要么dfna<dfng,dfnvdfnbendv,要么dfnvdfnaendv,dfnb>endg
  2. u不是v的祖先的时候,显然dfnudfnaendu,dfnvdfnbendv

第一种情况构成了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表示第i1的列编号。在p_1列放第二个1n-1种方案,假设第二个1行号为q_i,那么接下来考虑p_{q_i}列,这列第二个1n-2 种放法,因为不能在此时返回第一行,再加上已有21的行不能再放1。接下来就是n-3...。除以二是因为这个过程的逆过程也被计算过了。

C

一眼费用流裸题,但是数据范围有点大,考虑动态维护流量。

设当前加入的点编号为x,因为深度是O(\log n)的,因此我们可以枚举xx要到的点的LCA,对于当前LCA设为g,我们需要求出g往子树中走最小的代价使得可以流到一个还有剩余容量的点,设为down_g。注意子树中行走的代价可以根据每条边的流量正负来确定,因此要维护每条边的流量,其实就是手动维护网路流。我们需要求出down_g+cost(x\rightarrow g)中代价最小的那个,然后暴力维护每条边的流量即可。

复杂度O(n\log n)

Comments

No comments yet.

Post a comment

You can use @mike to mention the user mike.

If you wish to input the '@' character, please use @@