2023.10 ~ The future breaking out of shades from the past / Still ablaze

CF1767F

dsu on tree 之后,每个子树都是一个前缀。现在变成了一个长为 \(O(n\log n)\) 的序列,有 \(q\) 次区间颜色数查询。直接莫队,取块长为 \(B=\frac{n\log n}{\sqrt{q}}\),复杂度就是 \(O(n\log n\sqrt{q})\)。好像可以把 sqrt 放进 log 里,这个后面再说。

然后最小众数这个东西。。大概还要根号平衡一下

具体做法大概是 先开桶维护值域 然后再对每块用桶的值域维护值域分块 就行了

Luogu7916

可以发现求的就是一个多源多汇的网络流

但是点数边数都是 \(O(nm)\),单次复杂度 \(O(\text{maxflow}(nm,nm))\) 肯定是过不去的

考虑转对偶图最短路,发现这个不一定能转成平面图,但是能做 \(k=2\) 拿 80

考虑 \(k>2\),考虑建出 \((n+1)\times(m+1)\) 个点的平面图,外部建一圈点,一开始边权都是 \(0\),如果有附加点就相当于把外部两个点之间的边权赋值成他的点权。对每个附加点跑一遍 dij 算出他到别的所有点的最短路,可以证明此时最优方案一定是不交的,直接 DP 即可。

复杂度 \(O(\sum k_inm\log(nm)+\sum k_i^3)\)

Luogu8820

\(f_{u,0/1/2}\) 表示当前考虑到 \(u\) 这个点,上一个点和他的距离是 \(0/1/2\) 的最小代价,其中 \(0\) 就表示选择这个点自己。转移大概是 \(f_{u,j}+w_v\to f_{v,0},f_{u,j}\to f_{v,j+1}\) 分别表示选/不选 \(v\)

但问题在于可能会跑出去,但我们发现一定是跑出去之后立刻跑回来,并且一定是跑到 \(u\) 的最小兄弟这个位置,那我们把这个操作看作从 \(f_{u,1}\) 可以转移到 \(f_{v,1}\),具体来说就是

\[f_{u,1}+g_v\to f_{v,1} \]

其中 \(g_v\) 表示 \(v\) 的最小兄弟的点权。那么按照套路写成矩阵,令 \(F_u=\begin{bmatrix}f_{u,0}&f_{u,1}&f_{u,2}\end{bmatrix}\),有

\[\begin{bmatrix}f_{u,0}&f_{u,1}&f_{u,2}\end{bmatrix}\times\begin{bmatrix}w_v&0&\infty\\w_v&g_v&0\\w_v&\infty&\infty\end{bmatrix}\to F_v \]

其中乘法是 \(\min+\) 矩乘。

初值是 \(F_s=\begin{bmatrix}w_s&\infty&\infty\end{bmatrix}\)。于是只需要求出一条链上的矩阵乘积。

点分即可,复杂度 \(O(nk^3\log n+Qk^2)\)

Luogu7077

秒了

考虑每个加法的贡献,发现当操作序列中没有乘法的时候,顺序是无关紧要的,只需要算出它被运行的次数。把题目中的关系建出一张图,那么对于在 \(x\) 节点处的操作,对 \(y\) 产生的贡献就是 \(x\to y\) 的路径数。显然题目中的 \(Q\) 次操作等价于一次操作:我们新建一个根操作,让它对这 \(Q\) 次操作连边即可。那么没有乘法的时候直接算路径数就行了。

考虑有乘法咋办,发现只需要把 \(x\to y\) 的贡献应当是路径数乘上它后面的乘法操作的乘积。考虑算出 \(u\) 点的所有后继乘法操作的乘积 \(M_u\) 和贡献和 \(F_u\)。首先预处理出来 \(M_u\)

转移的时候我们倒序枚举所有出边,维护当前的乘积 \(mul\)(初始为 \(1\)),遇到一个出边 \(u\to v\) 的时候先执行 \(F_v\leftarrow F_v+F_u\times mul\),再让 \(mul\leftarrow mul\times M_v\)

初值是 \(F_{\text{root}}=1\),这样就能算出每个操作的贡献了。复杂度 \(O(n+m+Q+\sum C_i)\)

Luogu7078

可以发现如果当前最大的那条蛇吃完之后不会变成最小的或者只剩下它一个,那么其他任意的都一定吃不掉它,它就可以放心大胆接着吃。

如果最大的变成了最小的,考虑讨论一下,发现需要找到第一次“最大的吃完不会变成最小”的位置,根据奇偶性判断是否能再吃一次。

比如一开始 \(A\) 吃完最小的变成了最小的,然后 \(B\) 如果吃了 \(A\) 不会变成最小那 \(B\) 肯定就会吃掉 \(A\),那 \(A\) 这样一想就肯定不会去吃,所以这种情况就不会吃;如果 \(B\) 吃了 \(A\) 变成最小的,考虑接下来的最大值 \(C\),如果 \(C\) 吃了 \(B\) 不会变成最小的那就肯定吃,那 \(B\) 这么一想就肯定不会接着吃,\(A\) 经过深思熟虑决定吃掉当前的最小的,以此类推。

直接用 std::multiset 维护,复杂度是 \(O(n\log n)\)。但是其实已经能过了。。

考虑怎么做到线性。由于题目给出的序列本身有序,考虑维护两个队列 \(P,Q\),并保持两个队列均递增。一开始,\(P=(p_1,p_2,\cdots,p_n),Q=\varnothing\)。我们保证任意时刻均有 \(p_i\le p_{i+1},q_i\le q_{i+1}\)

设当前 \(P=(p_1,\cdots,p_x),Q=(q_1,q_2,\cdots,q_y)\),我们每次取出 \(p_x,q_y\),找到其中较大的作为最强蛇,可以确定此时最小的蛇必定是 \(p_1\),接下来必有:在最强蛇吃掉 \(p_1\) 之后,如果它不会变成最弱的,那么它必然小于 \(Q\) 中的所有元素,同时永远不会变成最弱的。因此可以直接将其放在 \(Q\) 的开头,然后接着模拟。

如果最强蛇吃掉 \(p_1\) 之后变成了最弱的蛇,可以发现上述性质仍然成立,因此接着模拟就行了。

这样时间复杂度就是 \(O(n)\)

Luogu5658

一开始看成需要是本质不同子串了,我说这是不是得来个广义 sam 啊,玉玉了

后来发现不是,那就简单了,考虑每次加一个字符算以他为右端点的字符个数,算出每个点到根的链上和(左括号为 \(1\),右括号为 \(-1\)),那么一个区间合法需要 \(S_r=S_{l-1}\),且区间 \([l,r]\) 中的每个 \(i\) 都满足 \(S_i\ge S_{l-1}\)。那也就是说 \(S_{l-1}\) 得是一个后缀最小值。

那考虑对每个 \(i\) 算出来 \(\text{cnt}[i]\) 表示 \(S_j=i\)\(j\) 恰好是后缀最小值的位置个数。那么加入一个点 \((x,S_x)\) 的时候对答案的贡献就是 \(\text{cnt}[S_x]\),接下来会把所有 \(i>S_x\)\(\text{cnt}[i]\) 赋值成 \(0\),然后令 \(\text{cnt}[S_x]\leftarrow \text{cnt}[S_x]+1\)

可以直接用数据结构维护,复杂度 \(O(n\log n)\);不过我们注意到每次 \(S\) 最多减一,因此后缀赋值其实只有单点赋值,所以直接做就是 \(O(n)\) 了。

ARC160C

\(f(i,j)\) 表示只考虑 \(\ge i\) 的数,多出来 \(j\)\(i\) 的方案数。毛估估一下发现状态数不超过 \(O(n)\),直接做就行。转移大概要前缀和优化一下。

具体来说,设 \(c_i\)\(=i\) 的元素个数,考虑每个 \(c_i\) 的贡献,发现是 \(\sum\lfloor\frac{c_i}{2^j}\rfloor\),这个不超过 \(c_i-1\),而我们都知道 \(\sum c_i=n\) 所以总状态数就是 \(O(n)\) 的了。算上还有一项 \(0\) 貌似应该是 \(O(n+\max A)\)

不过实际上两个位置如果相隔 \(O(\log n)\) 位就独立了,因此完全能做 \(A_i\le 10^9\) 的。

ARC160D

考虑把操作序列逆序,但直接计数操作序列显然是要算重的。

\(B_i\) 为以 \(i\) 为左端点的操作 \(2\) 个数,我们发现如果能合法那么一定存在一个 \(B_i<K\) 的方案,另一方面如果钦定 \(B_i<K\) 之后一个 \(A\) 一定唯一确定一个 \(B\),然后确定这个 \(B\) 之后操作 \(1\) 的方案也是确定的。另一方面显然操作序列可以对应到 \(A\) 上所以就一一对应了。

设在 \(i\) 位置进行 \(1\) 操作的次数分别是 \(C_i\),那么相当于 \(\sum B_i+\sum C_i=\frac{M}{K}\),并且需要 \(B_i<K\)

先把 \(M\) 除掉 \(K\)。容斥,钦定 \(i\)\(B_j\ge K\),方案数是 \(\binom{M-iK+2N-K}{2N-K}\)。于是答案就是

\[\sum_{i=0}^{N-K+1}(-1)^i\binom{N-K+1}{i}\binom{M-iK+2N-K}{2N-K} \]

直接暴力算组合数就能过了。如果对这个下降幂多项式做多点求值也能做到 \(O(N\log^2N)\)

整数拆分

\(n\) 拆成若干正整数使乘积最大:一定是尽可能多拆 \(3\),如果 \(\bmod 3=1\) 就拆一个 \(4\) 出来,余 \(2\) 就拆一个 \(3,2\) 出来,是 \(3\) 的倍数就全拆 \(3\)

一个题

给定一棵 \(n\) 个节点的树,边有边权,求两个点 \(x,y\),最小化 \(\sum_{i=1}^n\min(\text{dis}(x,i),\text{dis}(y,i))\)

\(1\le n\le 5\times 10^5\)

\(1\) 作为根,考虑枚举路径的中点,\(x\) 在它的子树内,\(y\) 在子树外,那么子树内的都由 \(x\) 决定,外面都由 \(y\) 决定。现在只需要对每个点求出子树的重心和子树补的重心。

子树的重心可以均摊 \(O(n)\) 求:\(f_u\) 表示 \(u\) 子树的重心,算 \(f_u\) 你就先确定重心在哪个儿子 \(v\) 里头,然后从 \(f_v\) 开始往上跳。这样一定只会一直往上跳,均摊 \(O(n)\)

考虑子树补咋做,设 \(g_u\) 表示 \(u\) 子树补的重心,那么考虑从 \(u\) 走到儿子 \(v\),新的重心一定在 \(g_u\)\(u\) 删掉 \(v\) 那边的子树连线上,发现这个就是除了 \(v\) 之外 \(\text{size}_p\) 最大的一个 \(p\)\(f_p\)。然后倍增跳就行了。

具体来说设 \(v\) 的子树补大小是 \(m\) 我们把这条链拉出来那么对一个点判断它是否有大小 \(>m/2\) 的子树,如果没有说明它是答案,否则看这个子树在哪一侧就行了。复杂度 \(O(n\log n)\)

ARC160E

考虑删掉一个点 \(i\),图中会出现 \(\deg_i\) 个连通块;我们要求附加边能够将这些连通块连通起来。

显然,所有叶子都必须被连接。当叶子个数为偶数 \(2k\) 的时候,我们设它们按照 DFS 序排序之后是 \(p_1,p_2,\cdots,p_{2k}\),那么将 \(p_i,p_{i+k}\) 配对一定合法。证明如下:

  • 如果删掉二度点,由于子树内 DFS 序连续,因此 \(p\) 会被分出来一个区间。显然按照我们这种连边方式,想要让两部分不连边,又得形成区间,必须得包含所有点。这显然不可能。
  • 如果删掉三度点,那么 \(p\) 会被分出来两段区间,和剩下一段补。考虑如果不连通,由于只有三个连通块,因此必然存在孤立的连通块。这样这个孤立的连通块必须包含所有点,也会导出矛盾。

考虑叶子个数是奇数怎么办。可以发现,只要保证删掉每个点后不存在孤立的连通块,方案就一定合法。钦定一个叶子 \(x\) 不参与匹配,剩下的按照刚才的方法连边,那么这个时候想要在删掉一个点后出现孤立的连通块,只有一种可能:删掉这个点后,有一个连通块中仅包含 \(x\) 这一个叶子节点。

我们发现这要求这个点到 \(x\) 的路径上全都是二度点(当然这个点本身可以是三度点),而一个这样的点对 \(x\) 的约束就是 \(x\) 必须连到其他的子树上。发现只有和 \(x\) 距离最近的一个三度点(显然是唯一的)能造成约束。

此时其实已经能做了,但我们再仔细考虑一下发现,任意一个点都一定能找到一个合法的这样的叶子,于是直接找非叶子中的最小权节点就行了。

Luogu9746

考虑设

  • \(f(l,r)=0/1\) 表示 \([l,r]\) 能否缩成一个点
  • \(g(l,r,v)=0/1\) 表示 \([l,r]\) 中是否有一个子区间能缩成 \(v\)

首先转移 \(g\),这个比较简单:

\[g(l,r,v)=g(l+1,r,v)\text{ or }g(l,r-1,v)\text{ or }(f(l,r)=1\text{ and } s(l,r)=v) \]

其中 \(s(l,r)=\oplus_{i=l}^ra_i\)\(\oplus\) 表示异或。

然后转移 \(f\)。考虑最后一次操作,由于任意时刻当前序列中的一个数都对应原序列中的一个区间,因此最后一次操作时大概就是左右端点在原序列中分别代表 \([l,p],[q,r]\),然后 \([p+1,q-1]\) 这个区间得能缩出来一个 \(s(l,p)\oplus s(q,r)\)。当然两边还得能缩起来。形式化来讲就是

\[f(l,p)=f(q,r)=g(p+1,q-1,s(l,p)\oplus s(q,r))=1 \]

这样做是 \(O(n^4+n^2a)\),考虑优化这个转移。实际上这个跑得比后面的 n^3 快一万倍

考虑把 \(g\) 再套一次,然后只枚举 \(p\)。具体来说设 \(h(l,r,v)\) 表示 \([l,r]\) 中能否选出 \(p\),使得

  • \(l<p \le r\)
  • \(g(l,p-1,v\oplus s(p,r))=f(p,r)=1\)

考虑怎么转移 \(h\)。显然可以枚举 \(p\) 直接做,但复杂度还是 \(O(n^3a)\);不过我们发现,由于 \(g\) 具有某种意义上的区间单调性,也就是说如果 \(g(l,r,v)=1\) 那么对任意 \(L\le l\le r\le R\) 都有 \(g(L,R,v)=1\)

因此,如果 \(h(l,r,v)=1\),那么对任意 \(L\le l\) 均有 \(h(L,r,v)=1\)(我们只需要取 \(p\)\(h(l,r,v)\) 选择的 \(p\) 就可以了)。只需要改成 \(h'(r,v)\) 表示最大的 \(l\) 使得原来的那个 \(h(l,r,v)=1\) 即可。

下面我们记 \(h(r,v)=h'(r,v)\)。为了计算 \(h(r,v)\),大概还需要算 \(w(r,v)\) 表示最大的 \(l\) 使得 \(g(l,r,v)=1\),然后算 \(h(r,v)\) 就只需要枚举 \(p\) 了。

这样这部分就是 \(O(n^2a)\) 了,于是总的复杂度就是 \(O(n^3+n^2a)\)。当然说的是单组数据。

关于构造方案:首先,我们可以在转移的时候顺便记录下 \(f(l,r)\) 选择的 \(p\),然后在构造方案的时候直接取 \(q=r\),这样显然也不会超过 \(O(n^3)\);接下来找到 \(p\) 之后,我们先递归地构造出 \([l,p]\) 的方案,然后对于 \(g\) 显然也只需要 \(f\) 的方案,因此差不多就可以构造了。

然后 \(g\) 大概还要记录一下合出来这个数之后位置在哪。

然后构造的时候顺便把下标偏移一下就可以了,想清楚还是比较好写的!

这个题是真nm抽象。。我写了 \(O(n^3+n^2a)\) 过不了一点,改成 \(O(n^4)\) 就乱过

DFS 序 LCA

求出 DFS 序之后,当 \(u\neq v\) 时,不妨设 \(\text{DFN}(u)<\text{DFN}(v)\)

那么 DFS 序在区间 \([\text{DFN}(u)+1,\text{DFN}(v)]\) 中深度最小的点的父亲就是 LCA

删除题目

考虑如果确定了选择的边集怎么算答案:不妨设这些边一直往上,那么可以发现 \(P\) 就是对每个相邻的两条边 \((u_1,v_1),(u_2,v_2)\),其中从下到上的顺序依次为 \(u_1,v_1,u_2,v_2\),对答案造成 \((\text{size}(u_2)-\text{size}(u_1))\times \text{size}(u_1)\) 的贡献。然后最上面那个点还要造成 \(\text{size}(u)\times(n-\text{size}(u))\) 的贡献。如果不是一直往上,那就是把两条链拼起来,发现会多算一部分,不过应该就是 \(\text{size}(u)\times \text{size}(v)\),其中 \(u,v\) 是两边最顶端的这个点。

考虑点分治,并钦定当前分治中心为根,重新计算下面这些点的 size。这部分可以用 Ynoi 这是我自己的发明 那个题,树剖一下 1log 算出来。

然后考虑 DP,先算出每个点 \(u\)\(f_u\) 表示钦定选 \((u,fa_u)\) 作为最顶上这条边的时候,他的最优的方案。然后考虑转移,正常是枚举 \(v\)\(u\) 子树内,然后转移到 \(f_v+(\text{size}(u)-\text{size}(v))\times \text{size}(v)\),发现是一个李焯熟的形式,考虑用李焯熟合并来维护这个东西大概就行。

然后考虑拼接两条路径,发现相当于找一个 \(v\) 使得 \(f_u+f_v-\text{size}(u)\times \text{size}(v)\) 最大,于是李超树就行了。

算上点分治的 log 一共是 2log 这个李焯熟的范围可以发现是 \(n\) 所以两个 log 都是 \(\log n\)

Maximized Combos

考虑对 \(0\) 之间的 \(1\) 的个数计数,由于一共有 \(n-m\)\(0\),因此会把 \(1\) 分割成 \(n-m+1\) 段。

考虑算最长连续段 \(\le s\) 的方案数,相当于对以下的序列 \(x_{1\cdots n-m+1}\) 计数:

  • \(\sum x_i=m\)
  • \(0\le x_i\le s\)

考虑容斥,钦定 \(k\)\(x_i>s\),插板可得方案数就是

\[\binom{n-m+1}{k}\binom{n-k(s+1)}{n-m} \]

于是答案就是

\[f(s)=\sum_{k=0}^{n-m+1}(-1)^i\binom{n-m+1}{k}\binom{n-k(s+1)}{n-m} \]

然后发现对于一个 \(s\) 这样的 \(k\le \frac{n}{s+1}\) 所以总复杂度根据调和级数是 \(O(n\log n)\)

QOJ6555 (The 2nd Universal Cup. Stage 5 , J)

先给 EI 磕三个

这是一个 \(O(\frac{n^3}{w})\) 的做法。由于作者本人在写这篇题解时才刚接触线代,所以可能某些地方比较显然的事实也会反复说几遍,见谅!/wq

首先考虑用 \(n\) 个变量 \(x_1,x_2,\cdots,x_n\in\{0,1\}\) 表示第 \(i\) 个点选不选,那么导出子图的边数的奇偶性就是

\[f(x_1,x_2,\cdots,x_n)=\left(\sum_{(i,j)\in E}x_ix_j\right)\bmod 2 \]

这是二次型,考虑把 \(f(v)\) 写成 \(v^\textsf{T}Av\) 的形式,其中 \(v\)\(x_1,\cdots,x_n\) 的列向量,\(A_{i,j}\) 是上面这个多项式中 \(x_ix_j\) 项的系数。我们需要求出所有列向量 \(v\in\mathbb F_2^n\)\(f(v)\) 之和。

我们考虑对 \(A\) 做一些变换来简化问题。考虑取矩阵 \(Q\),使得当 \(v\) 取遍 \(\mathbb F_2^n\) 的时候,\(Qv\) 也取遍 \(\mathbb F_{2}^n\)。那么就有

\[\sum_vv^\textsf{T}Av=\sum_{v}(Qv)^{\mathsf{T}}AQv=\sum_{v}v^{\mathsf T}(Q^{\mathsf T}AQ)v \]

于是我们就可以把 \(A\) 变成 \(Q^{\mathsf T}AQ\)。这里直接给出这三种变换:

  • 翻折

注意到 \(x_ix_j\) 的系数与 \(x_jx_i\) 的系数本质没有区别,因此我们可以对每个 \(i=2,\cdots,n\),令 \(A_{i,1}\leftarrow A_{i,1}+A_{1,i},A_{1,i}\leftarrow 0\)。容易发现这不会影响结果。这样一来,我们就把第一行除了 \(A_{1,1}\) 以外的数都变成了 \(0\)。如下:

\[\begin{bmatrix}A_{1,1}&A_{1,2}&A_{1,3}&\cdots &A_{1,n}\\A_{2,1}& &\cdots&\\A_{3,1}&&\cdots\\\vdots&&\ddots&&\vdots\\A_{n,1}&&\cdots&&A_{n,n}\end{bmatrix}\to\begin{bmatrix}A_{1,1}&0&0&\cdots &0\\A_{2,1}+A_{1,2}& &\cdots&\\A_{3,1}+A_{1,3}&&\cdots\\\vdots&&\ddots&&\vdots\\A_{n,1}+A_{1,n}&&\cdots&&A_{n,n}\end{bmatrix} \]

当然运算都在模意义下进行。

  • 找主元+消元

\(Q\) 为交换 \(x_i,x_j\) 对应的变换,即 \(Q_{k,k}=1(k\neq i,k\neq j),Q_{i,j}=Q_{j,i}=1\)

那么考虑 \(Q^{\mathsf T}AQ\) 是啥,发现就是先交换 \(i,j\) 两行,再交换 \(i,j\) 两列。这样就实现了交换两行。

那么这样一来,我们找到 \(i\ge 2\) 使得 \(A_{i,1}\neq 1\),然后就可以把 \(A_{i,1}\) 交换到 \(A_{2,1}\) 的位置。如果不存在这样的 \(i\),我们的目标就已经达成了,可以直接对第 \(2\) 行开始重复这个过程。

为什么不直接换到第一行?如果换到第一行,那么第一列也要被换走,然后就寄了

下面还要用这个去消掉别的 \(A_{i,1}\),其中 \(i\ge 3\)。假设要消掉第 \(j\) 行,方法是:取 \(Q\)\(x_j\leftarrow x_j+x_i\) 对应的变换,即 \(Q_{i,i}=1\)\(1\le i\le n\)),以及 \(Q_{i,j}=1\)。那么 \(Q^{\mathsf T}AQ\) 是啥呢,发现造成的影响就是,先把所有 \(A_{j,k}\leftarrow A_{j,k}+A_{i,k}\),然后再把所有 \(A_{k,j}\leftarrow A_{k,j}+A_{k,i}\)

这样一来,我们就能把矩阵中除了 \(A_{1,1},A_{2,1}\) 之外,第一行第一列的位置都消成 \(0\)。于是考虑一直这样做下去,就能在 \(O(n^3)\) 的时间内把矩阵变成只有 \(A_{i,i},A_{i,i-1}\) 非零的情况。

这种情况相当于图是一个带有若干自环的链,那么直接 DP 即可。

然后我们发现复杂度的瓶颈在消元那一步,考虑我们依次施加若干个变换 \(Q_1,Q_2,\cdots,Q_k\),那么原本的 \(A\) 就变成 \(Q_k^{\mathsf T}Q_{k-1}^{\mathsf T}\cdots Q_1^{\mathsf T}AQ_1\cdots Q_k=(\prod_{i=1}^k Q_i)^{\mathsf T}A(\prod_{i=1}^k Q_i)\),于是这个等价于一起做。

考虑先做行,发现如果我们维护的是行的 bitset 那可以直接做;然后再做列,注意到这个是把第 \(i\) 列异或到后面的某些列上面,考虑算出来这些列的 bitset,然后把对第 \(i\) 列上的每个 \(1\),就把这一行异或上这个 bitset。

这样总复杂度就是 \(O(\frac{n^3}{w})\)

有组合意义的解释:

我们考虑计算 \(\sum_{S\subseteq\{1,2,3,\cdots,n\}} (-1)^{cnt(S)}\),这里 \(cnt(S)\) 表示 \(S\) 集合的导出子图的边数。

我们记 \(x_i=[i\in S]\)

我们考虑删掉 \(n\) 号点。

注意到如果 \(x_i\) 的取值会影响 \(cnt(s)\) 的奇偶性,则正负相消,贡献为 \(0\)

所以我们需要保证下列条件满足:

\(\sum_{i=1}^{n-1}a_{n,i} x_i + a_{n,n}\equiv 0\pmod 2\)

我们考虑是否存在位置 \(pos\),满足 \(a_{n,pos}(pos\ne n) =1\)

1.如果不存在这样的 \(pos\),那我们根据 \(a_{n,n}\) 的取值分类讨论:
1.1.\(a_{n,n}=0\),则贡献乘 \(2\)
1.2.\(a_{n,n}=1\),贡献变成 \(0\)

2.如果存在一个位置 \(pos\),满足 \(a_{n,pos}=1\)

那么,根据 \(\sum_{i=1}^{n-1}a_{n,i} x_i + a_{n,n}\equiv 0\pmod 2\),我们可以得出:

\(x_{pos}\equiv \sum_{i=1\land i \ne pos}^{n-1} a_{n,i} x_i + a_{n,n} \pmod 2\)

我们考虑对于一个序列 \(x_1,x_2,\cdots,x_n\) 计算答案。

\[\begin{aligned} &\sum_{i=1}^{n}\sum_{j=i+1}^n a_{i,j} x_i x_j\\ \equiv&\sum_{i=1}^{n-1}\sum_{j=i+1}^{n-1} a_{i,j} x_i x_j\\ \equiv&\sum_{i=1\land i \ne pos}^{n - 1}\sum_{j=i+1\land j\ne pos}^{n - 1} a_{i,j} x_ix_j+\sum_{i=1\land i \ne pos}^{n-1} a_{i,pos} x_ix_{pos} + a_{pos,pos}x_{pos}\\ \equiv&\sum_{i=1\land i \ne pos}^{n - 1}\sum_{j=i+1\land j\ne pos}^{n - 1} a_{i,j} x_i x_j+\sum_{i=1\land i \ne pos}^{n-1} a_{i,pos} x_i(\sum_{i=1\land i \ne pos}^{n-1} a_{n,i} x_i+a_{n,n})+a_{pos,pos}(\sum_{i=1\land i \ne pos}^{n-1} a_{n,i} x_i+a_{n,n}) \end{aligned} \]

于是,我们就可以把 \(n\times n\) 的矩阵,在 \(O(\frac{n^2}{w})\) 的时间内,变成 \((n-2)\times (n-2)\) 的矩阵。

注意到 \(x_n\) 有两种取值,所以贡献要 \(\times 2\)。注意到上述式子继续展开,则 \(a_{pos,pos}a_{n,n}\) 的项,所以贡献可能 \(\times (-1)\)

总时间复杂度 \(O(\frac{n^3}{w})\)

LOJ3658

终于能上 LOJ 了!!!!!!冷静一下。

考虑对每种方案,设其交点数为 \(t\),我们就给答案加上 \((-1)^t\)。这样算出来的是偶 - 奇的方案数,加上总的方案数再除以二就是答案了。总的方案数可以简单算出,这里略过。

考虑一条边对奇偶性的贡献。发现如果这条边是 \((u,v)\) 其中 \(u<v\),那么 \([u+1,v-1]\) 中有连边的点数的奇偶性就是这条边对奇偶性的贡献。

先考虑要求图时完美匹配的情况,考虑一种颜色,如果相邻两个点没有直接连接上,那么我们交换相邻两个点的匹配点后,一定会改变符号。并且可以发现这些总是一一对应的。所以只剩下唯一一种相邻点全部两两匹配的方案,这种方案的贡献为 \(1\)

那多种颜色怎么办,还是考虑相邻点,我们考虑直接交换相邻点而不是它们的匹配点,那么总能交换成每种颜色单独成段的情况,且交换一次就改变一次符号。这个时候所有方案的权值和就都是 \(1\)。再算上前面的若干次交换,发现一个方案的 \((-1)^t\) 就是这个方案的 \(-1\) 的逆序对次方。

此时我们已经可以 DP 了,\(f(i,S,0/1)\) 表示考虑到前 \(i\) 个点,\(S\) 里面记录每种颜色的个数的奇偶性,\(0/1\) 表示逆序对奇偶性,可以做到 \(O(nA2^A)\),其中 \(A\) 为颜色数。

现在考虑不是完美匹配的情况,那么相当于选出若干个点,且每种颜色选偶数个,要造成 \(-1\) 的逆序对次方的贡献。考虑建图,若 \(a_i>a_j\) 就连边 \((i,j)\),那么就变成了上面那个题。但是这样没保证每种颜色个数为偶数,考虑对每种颜色建一个主点连向每条边,这样这种颜色选奇数次的方案就消掉了。

那当然可以做到 \(O(\frac{n^3}{w})\)

LOJ3626

考虑这个矩阵长啥样,首先显然 \(A\) 不能重复否则答案是 \(0\)(有两行两列相同)。

\(A\) 重标号为 DFS 序的顺序,那么行列式的值不改变,因为交换 \(A_i,A_j\) 相当于同时交换两行两列。

考虑把权值 \(v\) 做树上差分,令 \(B_u=v_u-v_{fa(u)}\),那么就等价于对每个 \(i\)\(i\) 子树内的所有点形成的这个矩阵中的每个值都加上 \(B_i\)。那子树的 DFS 序是连续的,所以相当于做一个矩形加。

矩阵上做二维差分不影响行列式,考虑二维差分,那么矩形加就变成了四个单点加。

假设这个对应的 DFS 序区间是 \([l,r]\),那么相当于 M[l][l]++,M[r+1][r+1]++,M[l][r+1]--,M[r+1][l]--,发现这个类似于矩阵树的 Kirchhoff 矩阵,那相当于建一个图出来,然后对每个点连边 \([l,r+1]\),要数生成树个数。

那怎么做呢,发现由于各子树 DFS 序要么包含要么不交,然后你发现任取一个子图如果想同胚于 \(K_4\) 那最后我们发现肯定会出现相交,所以这个是广义串并联图,套广义串并联方法就行了。

时间复杂度 \(O(n\log n)\)

ABC294Ex

按照广义串并联图的 rake & compress & twist 方法缩减图的规模后,每个点的度数都 \(\ge 3\)

具体来说,我们对每条边维护 \((f_e,g_e)\) 表示其两端相等/不相等的贡献,同时维护当前的答案 \(ans\),并不断进行以下三种操作直到无法进行:

  • 删一度点:设这个一度点旁边的这条边是 \(e\),那么相等的方案为 \(1\),不相等的方案为 \(k-1\),于是我们应当让 \(ans\leftarrow ans\times(f_e+(k-1)g_e)\),然后删掉这个点和它的邻边。
  • 缩二度点:设二度点的两端分别是 \(x,y\) 这两条边,那么缩完后,新边两侧相等的贡献应当为 \(f_xf_y+(k-1)g_xg_y\),不相等的方案数为 \(f_xg_y+g_xf_y+(k-2)g_xg_y\)
  • 叠合重边:设两条边分别为 \(x,y\),不难发现直接叠合为一条 \((f_xf_y,g_xg_y)\) 这样的边即可。

只要图中有度数 \(\le 2\) 的点,我们便可以一直操作下去。当操作停止时,对每个 \(i\) 均有 \(\text{deg}_i\ge 3\)

于是有

\[2m=\sum_{i=1}^n\text{deg}_i\ge 3n \]

由于 \(m\le 30\),因此有 \(n\le 20\)

然后就可以用集合幂级数优化状压 DP 做到 \(O(m^22^{\frac{2}{3}m})=O(m^21.587^m)\)

具体来说设 \(f(i,S)\) 表示用 \(i\) 种颜色给 \(S\) 染色的方案数,那么转移可以枚举 \(T\) 都染成颜色 \(i\),于是

\[f(i,S)=\sum_{T\subseteq S}f(i-1,S-T)\times w_1(T)\times w_2(S-T,T) \]

其中 \(w_1(T)\) 表示 \(T\) 中的点全都同色的贡献,即两端点都在 \(T\) 中的边的 \(f\) 之积;\(w_2(A,B)\) 表示一端点在 \(A\) 中,一端点在 \(B\) 中的所有边的 \(g\) 之积。

首先,如果存在一条边的 \(g_e=0\),那么这条边的两个端点的颜色必须相同,于是我们可以把图做一个 contract 即 \(G\leftarrow G \setminus e\)。下面我们假定所有边均满足 \(g\neq 0\),那么对于一个集合 \(A\),重新记 \(w_2(A)\)\(A\) 中点的颜色两两不同的贡献,即两端点均在 \(A\) 中的边的 \(g\) 之积。那么转移方程就是

\[f(i,S)=\sum_{T\subseteq S}f(i-1,S-T)\times w_1(T)\times \frac{w_2(S)}{w_2(S-T)w_2(T)}\\ \]

改一下形式就是

\[\frac{f(i,S)}{w_2(S)}=\sum_{T\subseteq S}\frac{f(i-1,S-T)}{w_2(S-T)}\times \frac{w_1(T)}{w_2(T)} \]

\(F_i(x)=\sum_{S}x^S\frac{f(i,S)}{w(S)}\) 即其集合幂级数,\(W(x)=\sum_{S}x^S\frac{w_1(S)}{w_2(S)}\),那么有 \(F_i=F_{i-1}\times W\)\(F_0=1\),答案即为 \([w_2(U)x^U]F_k\)。其中乘法是异或卷积,\(U=\{1,2,\cdots,n\}\)

于是只需要算出 \(W^k\)。套路地先 ln 后乘 \(k\) 再 exp 即可。

LOJ3050

  • 1_998244353

发现前面都是 \(19\) 的幂,拿 python 试试发现就是输出 \(19^{n}\bmod 998244353\)

写个代码发现,怎么 software3 寄了。打开一看发现出题人很没有树脂,输入了非常大的 \(n\)

无所谓,大家都会欧拉定理,直接输入的时候对 \(p-1\) 取模即可。

  • 1?

\(998244353\) 变成了问号,合理猜测我们需要自己找出模数。

打开 software4 发现输出都不大,合理猜测模数不大,我赌这个模数是 \(1234567\) 你信不信。

写个程序枚举一下模数,发现出题人很没有树脂,给了个很大的 \(n\)

没有模数我们又没法欧拉定理,这下这下了。难道要高精度启动了吗,并不,我们枚举模数的时候顺便线性筛算个 \(\varphi\),每次模一遍就行。我懒了,没写线性筛,暴力算的 \(\varphi\)

我草。。。。。。模数是 \(1145141\),绷不住了

虽然只靠第一个比较大的询问跑出来的有两个解,但是我相信,\(1145141\) 绝非巧合。。。

  • 1?+

这个 + 就很有意思啊。合理猜测是上面那玩意的加强。那你早说啊,我直接做加强版了。

合理猜测还是要找一个模数。但是看上去好像挺大啊这个模数,有 \(10^{18}\)

额咋做啊,先放着,等会再来写

LOJ3051

没看题解切了

发现阵营和派系之间大概是独立的。考虑先确定阵营,再确定派系。

先考虑最简单的情况:所有学校的城市两两不同,且 \(k=0\)

我们进行两次计数,第一次确定每个学校所属的派系,第二次确定阵营,不难发现对于两边方案的任意组合,总能一一对应一种实际的方案。那么答案就是两次计数的结果的乘积。

如果只有阵营的限制是好做的:\(f(i,j)\) 表示考虑了前 \(i\) 个学校,当前蓝阵营人数总和为 \(j\) 的方案数,那么设当前的总人数是 \(S=\sum_{x\le i} s_x\),可以算出来红阵营的人数为 \(S-j\)。时间复杂度 \(O(nM)\)

派系也是类似的。现在考虑加入城市的限制,也就是若干学校可能会需要选择同一个阵营。

这也就是说,我们在分配阵营的时候,需要把这些学校当作一个整体来 DP;而在分配派系却不需要。那么时间复杂度也是 \(O(nM)\)

最后我们考虑那 \(k\) 个有特殊要求的学校怎么做。考虑先不管这些学校和它们所属的城市,把别的算出来。然后对于一个含有特殊要求的城市,我们考虑对它选择的阵营讨论一下。发现相当于是,如果选了某一方,那么某些学校的方案是唯一的。

啊啊啊,不装了,我直接 GF 启动!可以发现上面其实本质上就是维护二元多项式,但是把 \(x,y\) 两维分开做了。

考虑每个城市,发现他对答案那个 GF 的贡献大概是,\(F_i(x)+y^cG_i(x)\),那感受一下应该就会写了吧,维护 \([x^iy^j]A(x,y)\),每次卷一个这种东西上来。那卷这东西咋整呢,发现我们仍然可以提出来 \(F_i\)\(G_i\) 的公因式(就是那些没有特殊要求的),它们乘起来是 \(H_i(x)\) 那么这个卷上去的大概是一个

那等价于我们先卷个 \(H_i(x)\) 上去然后再把 \(F_i,G_i\) 剩下的卷上去这样子。那我们都知道 \(F,G\) 里面不超过 \(O(k)\) 项直接做就是 \(O(nM+kM^2)\)

这题感觉给了很多,\(s_i\le 10\) 应该可以把相同的 \((1+x^a)\) 合并起来然后一起做一些多项式操作。。

我日,怎么被卡常乐,这不是正解吗???题解,启动

卧槽,怎么复杂度是个 \(O(kMs)\) 这种东西,先关下题解,让我思考一下

还是考虑那 \(k\) 个多项式嘛,哦我知道了大概是最后答案要求的是 \(A\) 的一个矩形和,那这个就相当于卷上一个 \(\frac{1}{(1-x)(1-y)}\) 然后求四项。考虑先把那 \(k\) 个多项式的乘积算出来,注意 \(x\) 的次数不超过 \(O(ks)\) 因此复杂度是 \(O(k^2sM)\),然后再把 \(\frac{1}{(1-x)(1-y)}\) 卷到前头的 \(A\) 上去,最后求一项就只需要 \(O(ksM)\) 的时间了。总的复杂度就是 \(O((n+k^2s)M)\)。然后就过了。

LOJ3052

没看题解啊,但是就一不小心看了一眼 LOJ 讨论区啊,然后看到有人说启发式合并一下子就会了啊

考虑一个贪心:维护集合 \(S_u\) 表示子树 \(u\) 内部在最优情况下选出的 \(\max M\) 的集合。我们对每个点 \(u\),先递归进子树算出所有儿子 \(v\)\(S_v\),接下来把所有的 \(S_v\) 合并起来,再把 \(M_u\) 插入进去,得到的就是 \(S_u\)。最后 \(S_1\) 中的数就是答案。

具体来说,合并两个集合 \(S,T\) 时,我们先把大小不足的那一边补 \(0\),然后设 \(S,T\) 中元素从大到小排序后的结果分别是 \(s_1\ge s_2\ge\cdots \ge s_k,t_1\ge\cdots\ge t_k\),然后再做一个匹配 \(i\to p_i\),对于一个匹配边 \((x,y)\) 我们会在合并的集合中插入 \(\max(s_x,t_y)\),现在我们需要最小化最后得到的集合的元素和。

这部分是好做的:注意到匹配之间一定不会相交,因此一定是按顺序依次匹配。于是我们可以考虑用 std::multiset 维护集合,在子树之间做启发式合并。

在合并的时候做双指针,复杂度大概是一个 \(O(n\log n)\)

下面我们来证明该做法的正确性。我们来证明以下事实:设 \(\varphi_p(A,B)\) 表示 \(A,B\) 两个集合用 \(p\) 这一匹配合并后得到的集合(其中 \(p\) 是一排列),\(\varphi(A,B)=\min_p\varphi_p(A,B)\)\(\text{sum}(A)\) 表示 \(A\) 中元素和,那么对任意的 \(A,B\),如果 \(\text{sum}(A)\le \text{sum}(B)\),那么对任意的 \(C\) 都有:

\[\text{sum}(\varphi(A,C))\le \text{sum}(\varphi(B,C)) \]

\(A,B,C\) 中的元素分别为序列 \(a,b,c\),那么 \(\sum a_i\le \sum b_i\)。设 \(p\) 为最优方案对应的匹配。

考虑每个 \(i\)\(\varphi_p(A,C)-\varphi_p(B,C)\) 的贡献:

  • \(c_{p_i}\ge a_i,c_{p_i}\ge b_i\),其贡献为 \(c_{p_i}-c_{p_i}=0\)
  • \(c_{p_i}\le a_i,c_{p_i}\le b_i\),其贡献为 \(a_i-b_i\)
  • \(a_i\le c_{p_i}\le b_i\),其贡献为 \(c_{p_i}-b_i\le a_i-b_i\)
  • \(b_i\le c_{p_i}\le a_i\),其贡献为 \(a_i-c_{p_i}\le a_i-b_i\)

等会,\(c_{p_i}-c_{p_i}\) 可以 \(\ge a_i-b_i\)?这咋整啊,好像有反例

但是对这个题的限制而言,好像构不出来反例?这啥情况

哦,我是不是可以证明这样一直合并过来,如果 \(\text{sum}(A)\le \text{sum}(B)\),那么 \(A\) 一定完全偏序 \(B\)

考虑如果 \(A\) 完全偏序了 \(B\),是否有 \(\varphi(A,C)\) 完全偏序 \(\varphi(B,C)\)

哦哦这不是显然吗,如果 \(a_i\le b_i\)\(\max(a_i,c_{p_i})\le \max(b_i,c_{p_i})\) 肯定也成立的啊。

你先别急我们还有一个操作是在集合里直接插入一个数,那这个还能保证完全偏序吗?考虑插入一个 \(x\),如果在 \(b\) 序列里插到了 \([i,i+1]\) 之间,\(a\) 序列放到了 \([j,j+1]\) 之间,那么显然有 \(i\le j\)

此时序列被分为三段:

\[\begin{matrix}b_1&b_2&\cdots&b_i&x&b_{i+1}&\cdots&b_{j-1}&b_j&b_{j+1}&\cdots&b_k\\ a_1&a_2&\cdots&a_i&a_{i+1}&a_{i+2}&\cdots&a_{j}&x&a_{j+1}&\cdots&b_k\end{matrix} \]

可以发现 \([1,i]\)\([j+1,k]\) 的部分仍然是完全偏序的。对于 \([i+1,j]\) 这一部分,可以发现有

\[a_{i+1}\le a_{i+2}\le\cdots\le a_j\le x\le b_{i+1}\le\cdots\le b_j \]

因此仍然是完全偏序。这样就完整地完成了证明。

LOJ3053

我们所可以自慰的,想来想去,也还是所谓对于将来的希望。
希望是附丽于存在的,有存在,便有希望,有希望,便是光明。

相当于存在一个点,它的大小为 \(L\) 的邻域范围完全覆盖了所有连通块,而且它得在所有连通块内。

能不能钦定这个点啊,但是会算重,那我们容斥嘛,钦定点集 \(S\),找到它们大小为 \(L\) 的邻域的交,然后连通块得在这里头选点,而且还得包含 \(S\) 以内的点。

然后你考虑钦定 \(S\) 之后如果不连通,那 \(S\) 的虚树上的点集也肯定是符合条件的,也就是说设 \(T\)\(S\) 的虚树的点集,那么钦定 \(S\) 的答案等于钦定 \(T\) 的答案。那类似 SDCPC2023 那个题,考虑对一个连通块计算其容斥系数,发现只要这个虚树存在一个 \(\deg\ge 2\) 的点,那么这个点删和不删不影响虚树这个点集,但是符号相反,这意味着这个点集的容斥系数为 \(0\)

于是我们只需要考虑点和两个相邻点,其容斥系数分别为 \(1\)\(-1\)

先考虑一个点怎么算答案,那相当于需要算出一个点大小为 \(L\) 的邻域中存在多少个包含他的连通块。考虑设 \(f(u,j)\) 表示从 \(u\) 的子树内前 \(j\) 层选连通块的方案数。由于钦定了子树内,最后我们还需要做一遍换根才能得到每个点的正确答案。那么转移就是

\[f(u,j)= \prod_{v\in\text{son}(u)} (f(v,j-1)+1) \]

并且我们还需要支持换根。然后先别急着优化我们来考虑一下边的 DP 该怎么算。

发现这也是类似的,对于一条边 \((u,fa_u)\),相当于在 \(u\) 的子树内 \(L-1\) 层选连通块,然后 \(u\) 的子树外以 \(fa_u\) 为中心选 \(L-1\) 层连通块再乘起来。那你发现这个仍然只需要支持算 \(f\) 以及换根。

具体来说我们可以在换根的时候如果当前准备从 \(u\) 换到儿子 \(v\),那肯定要先算出来 \(u\) 的除了 \(v\) 之外的儿子的信息并,然后我们拿这个信息并的 \(L-1\) 位置乘上 \(v\)\(L-1\) 位置来更新答案,然后再把这个线段树全局 \(+1\) 合并上去。

那我们来考虑优化嘛。要不来想想线段树合并?首先需要改成 \(f(u,j)\) 表示在 \(\text{dep}\le j\) 的子树内的选点的方案数,那每次相当于全局 \(+1\),合并的时候是对应位置相乘,于是需要维护区间 add,mul。

那换根怎么做?发现需要维护前后缀的线段树乘积,这个肯定不能暴力维护,是不是得可持久化啊。

感觉直接算前后缀乘积貌似是错的,那我们分治嘛,分治到 \([l,r]\) 的时候把左侧合并上来递归到右边,再把右边合并上来递归到左边,那复杂度是不是对的啊。不过是 2log,这是不是死定了啊

唉这个 N=1e6+5 写得我心里发慌啊。

等会这个分治复杂度真的对吗???线段树合并真的能换根吗???不是很懂啊,扔了,看题解


V-E 容斥什么东西啊,看上去和我那个本质一样的吧。好好好,长剖启动

考虑 \(f\) 嘛,那很简单嘛,相当于要维护全局 \(+1\) 和单点乘一个数,那直接线段树呗。注意这里虽然我们最多维护到 \(len_u\),但是外头其实都是有值的也要有贡献,发现这个相当于后缀乘。

那我们得有点希望嘛对吧,来个线性行不行啊?算了待会再说。

总结一下,我们长剖是维护一个总的数组 \(F\),其中在 DP 到点 \(u\) 的时候,实际上的 \(f(u,j)\) 的值应当为 \(F[dfn_{u}+j]\)。线段树维护的自然也是 \(F\)

然后怎么换根呢这个,可以发现如果要进入 \(u\) 的子树,设 \(len_u\) 表示 \(u\) 到子树内点的最远距离,那么只需要把 \([L-len_u-1,L]\) 的信息传下去就行了。那于是我们如果要进入轻子树,只需要暴力地把对应位置乘上去。

那进入重子树(长子树?)怎么办嘛,我们当然还是想直接继承。

然后大概还需要想一下,这个时候我们不能把 \(f(u,j)\) 映射到 \(F[dfn_u+j]\) 了,因为我们需要的 \(j\) 有效的条件应当是 \(L\ge j\ge L-len_u-1\)。牛魔的我直接 vector 启动

那我把 \(f(u,j)\) 存到 \(top(u)\) 所在的 vector 里面的 \(j+dfn_u-dfn_{top(u)}\) 里面,现在新的 \(f(u,j)\) 应当存到 \(j-L+len_u+1-dfn_{top(u)}+dfn_u\) 的位置。

然后你发现这样映射的话 \(f(u,j)\) 恰好对应上了 \(f(v,j+1)\),非常好啊。当然没对上也无所谓其实。

那进重儿子就只需要全局 \(+1\) 了。你先别急,我们换根的时候还需要做删除子树,那这个咋办呢。先考虑进轻子树,发现这部分我们可以暴力预处理前后缀乘积。考虑重子树,感觉还是类似做就行了。

大概想明白了,重子树就是再把轻儿子做一遍合并上来嘛。那就没啥问题了。


线性:

我们首先把加法解决掉。维护加法标记 \(a\),然后每次更新的时候我们本来应该让 \(f(u,0)\) 赋值成 \(1\) 的,但是我们想让每个位置如果是 \(x\) 那么实际的值是 \(x+a\),那我们就先把 \(a\leftarrow a+1\),然后把这个 \(f(u,0)\) 赋值成 \(1-a\) 就行了。

然后另一方面还有后缀乘的操作,那同理如果乘的是 \(m\) 我们就把全局乘上 \(m\) 再把前缀除掉 \(m\),可以发现这部分复杂度依旧只和轻链的链长相关,于是不影响总的复杂度。那维护的标记就变成了 \((a,m)\),表示我们 \(f\) 里面的值的如果是 \(x\) 那么他的实际值是 \(mx+a\)。这样可能逆推的时候需要算逆元,不过直接同步维护 \(im\)

但是还有一个问题是 \(m\equiv0\pmod p\),其中 \(p=998244353\)。那你发现这个相当于后缀赋值为 \(0\),但经过一系列的加和乘之后可能不是 \(0\) 了,那我们可以维护一个 \(L,w\) 表示 \(u\) 所在的长链从 \(L\) 开始的值都是 \(w\)


摆了

10.30 D

给一棵树,求链上众数,强制在线。

考虑随机撒点 \(B\) 个点,然后每个点到根的路径上第一个关键点和他的距离都 \(\le \frac{n}{B}\)

预处理关键点之间两两的众数,这部分 \(O(nB)\)

然后预处理 \(f(i,j)\) 表示第 \(i\) 个关键点到根的路径上 \(j\) 的数量,再求个 LCA 就行。

但是关键点的 LCA 不一定是关键点咋办捏,无所谓,随机完之后求个虚树就行。

总复杂度 \(O(nB+\frac{nq}{B})\),取 \(B=\sqrt{q}\) 有复杂度 \(O(n\sqrt{q})\)

学习了一下正经点的树分块

考虑钦定块的大小为 \(B\),我们可以将树做如下的划分,使得每块大小在 \([B,3B]\) 之间。

考虑自底向上维护,DFS 进入一个点最后出来会带一个包含根的连通块,那我们就在 DFS 一个点 \(u\) 的时候依次访问其儿子,每次 \(\ge B\) 就新开一块,对应到代码上就是把当前点 \(u\) 标记为关键点。然后最后可能会有一些 \(<B\) 的剩余,那就接着返回到上一层。

目前分出来的块的大小都在 \([B,2B]\) 之间,最后可能会剩一些,我们直接不管它们放到 \(1\) 所在的最后一块内,那么这一块的大小也不超过 \(3B\)

10.31 C

忘了 DDP 咋写了..

我们总结一下 DDP,如果最后状态设计出来会出现 \(f_{u,1\cdots k}\) 这样的状态,那么我们应当把轻儿子的信息合并,算出一个 \(k\times k\) 的矩阵 \(G_u\)\(G_{u,i,j}\) 表示重儿子 \(v\)\(f_{u,i}\) 这一状态该如何与轻儿子和他自己的总体信息并的 \(f_{v,j}\) 合并。

以本题为例,\(f_{u,0/1}\) 表示 \(u\) 点是 \(0/1\) 的概率,\(G_{u,i,j}\) 的含义应当是当重儿子为 \(i\) 的时候,最后算出来的值是 \(j\) 的概率。这个如果知道了轻儿子的 \(f\) 就可以直接算出。对于叶子节点,其 \(G=f\)

这样,一个节点的 \(f\) 就是这个节点重儿子的 \(f\) 右乘上它的 \(G\),一直递归下去就可以得到,我们只需要算出这一条重链上面的 \(G\) 自底向上一直右乘过来的答案即可。注意我们只维护 \(G\),换言之我们保证 \(G\) 在任意时刻都是正确的,但 \(f\) 则不一定。

现在我们需要维护修改,这首先会改变这个节点自己的 \(G\),进而改变其到根的路径上所有轻边上方节点的 \(G\)。为了计算这些节点的 \(G\),我们还需重新计算它们轻儿子的 \(f\) 之信息并。

本题中树为二叉树,直接计算即可;但在更一般的题目中并没有这么容易:一个点可以有多个轻儿子,如果直接将多个轻儿子的信息一同计算入内,复杂度无法接受。

这个时候我们可以对每个点再维护一个线段树来做;当 \(G\) 支持删除操作的时候也可以直接删除。

10.31 D

拜谢 alpha 大跌,dwt 大跌指导

先考虑乘积咋算。对每个 \(p\) 算他在答案里的指数 \(\ge i\) 的方案数,考虑算 \(<i\) 的方案数,处理出来 \(1\sim n\) 中有多少个 \(m\) 满足 \(v_p(m)<i\) 然后算 \(k\) 次幂就行了。这样就统计完了一个 \(p\) 的贡献。

这样就算完了乘积。\(n\) 这么小肯定咋写复杂度都爆不了。考虑和怎么算。

考虑根号分治,\(\le \sqrt{n}\) 的质数只有 \(2,3,5,7,11,13,17,19\)

它们的幂分别不超过 \(8,5,3,3,2,2,2,2\),这部分状态数为 \(\prod(w_i+1)=69984\)

考虑钦定这部分的 LCM 是 \(S\) 的约数算权值和,最后做高维差分。

考虑怎么算这个,把符合条件的数拎出来然后只考虑它们的大质数,现在就变成了原问题但是序列中全都是质数的情形。考虑每种质数一起转移是不是就行了啊。转移大概是

\[f(i-1,j)\times\binom{j+x}{x}\times (\texttt{x>=1?p:1})\times cnt(i)^x\to f(i,j+x) \]

其中 \(cnt(i)\) 表示第 \(i\) 个大质数的出现次数。发现复杂度 \(O(nk^2)\) 寄飞了。

考虑上面其实是在算 \([k!x^k]\prod (p_i(e^{cnt(i)\times x}-1)+1)\),做换元 \(t\leftarrow e^x\) 可以发现求的就是

\[[k!x^k]\prod (p_ie^x+1-p_i)=\sum_{w=1}^n[w^kt^w]\prod(p_it^{cnt(i)}+1-p_i) \]

后面是二项卷积啊,那可以直接 \(O(n^2)\) 暴力算的。分治 FFT 可以 \(O(n\log^2 n)\) 来着。

其实有组合意义,考虑 [选]*p + [不选]*1 = [选]*p + [不选]*p + [不选]*(1-p) = [随便]*p + [不选]*(1-p),然后考虑暴力是钦定大质数中的某些随便,设这些大质数的总数为 \(c\),由于剩下的都是不选一定不可能放进这个 \(k\) 里面。那么就是带上 \(c^k\) 乘上这些大质数的乘积的权值,然后乘上剩下的 \(1-p\) 的乘积。

那现在复杂度是 \(O(n^2S)\) 还是过不去啊,其中 \(S=69984\),但我们注意到如果钦定选了一个大质数还得乘上一个小质数,那么小质数的限制就变成了不能超过 \(\sqrt{n}\) 也就是说如果小质数超过了 \(\sqrt{n}\) 那大质数就全都是 \(1\) 了。大质数不是 \(1\) 的情况再算算发现小质数的幂次变成了 \(4,2,1,1,1,1,1,1\) 状态数就是 \(T=960\),我们拿一个 map 压一下就好了。于是复杂度是 \(O(Tn^2+Sn)\)

posted @ 2023-11-01 09:23  云浅知处  阅读(87)  评论(0编辑  收藏  举报