4 月做题记录

\(\text{2025/4/1}\)

Luogu P2585 [ZJOI2006] 三色二叉树

递归建树,树形 DP 随便做。

Luogu P5007 DDOSvoid 的疑惑

先考虑毒瘤集计数,令 \(g_u\) 表示 \(sub_u\) 内的毒瘤集个数,那么对于每个儿子 \(v\) 都可以从 \(g_v\) 个里选一个或者不选,于是

\[g_u=\prod_{v\in son_u}(g_v+1) \]

注意这个包含了空集的情况,我们正好让这种情况选择 \({u}\) 本身。

然后考虑计算所有毒瘤集的价值和,相当于每个 \(v\)\(g_v\) 个毒瘤集中选择一个来加,对每个毒瘤集算贡献,则 \(sub_v\) 中的毒瘤集要乘上其他子树的毒瘤集个数的系数,也就是 \(\frac{g_u}{g_v+1}\)。令 \(f_u\) 表示 \(sub_u\) 内的价值和,\(w_u\) 表示点 \(u\) 的价值,则

\[f_u=w_u+\sum_{v\in son_u}\frac{f_vg_u}{g_v+1} \]

直接做就是 \(\mathcal{O}(n\log{n})\) 的,可以通过。瓶颈在于计算逆元。

Luogu P3576 [POI 2014] MRO-Ant colony

终点状态唯一确定,考虑从食蚁兽所在的边 \((x,y)\) 开始做树形 DP。为了方便,把 \((x,y)\) 断开,建虚点 \(0\),在 \((0,x)\)\((0,y)\) 之间连无向边。令点 \(u\) 走向 \(0\) 被吃掉的合法初始状态范围为 \([l_u,r_u]\),从 \(u\)\(v\in sub_u\) 转移:

\[\begin{align*} l_v & =l_u(deg_v-1) \\ r_v & =(r_u+1)(deg_v-1)-1 \end{align*} \]

注意 \(v\) 是叶子的时候特判一下乘上 \(1\) 而不是 \(0\)。然后对 \(m\) 排序,对每个叶子节点在 \(m\) 上二分出合法的蚁群数即可。时间复杂度 \(\mathcal{O}(n\log{m})\)

\(\text{2025/4/4}\)

Luogu P10957 环路运输

断环成链,转化成满足 \(|i-j|\leq\frac{n}{2}\),枚举 \(i\),单调队列 \(\mathcal{O}(n)\) 维护 \(a_i-i\)

\(\text{2025/4/5}\)

Luogu P4381 [IOI 2008] Island

基环树直径有两种可能:

  • 不经过环:对每个环上节点的子树求直径即可。
  • 经过环:对每个环上节点求出从它开始,不经过其他环上节点能到达的最远距离 \(d_i\),那就和 Luogu P10957 一样了,只不过变成了环上两点路径走较大的那条,限制条件变为 \(|i-j|<n\)

时间复杂度 \(\mathcal{O}(n)\)

Luogu P3455 [POI 2007] ZAP-Queries

显然 \(\gcd(x,y)=d\Leftrightarrow \gcd\left(\frac{x}{d},\frac{y}{d}\right)=1\),于是我们需要快速求解形如

\[\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=1] \]

的式子。用莫比乌斯函数展开 \(\varepsilon(\gcd(i,j))\),变成

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{d\mid\gcd(i,j)}\mu(d) \]

变换求和顺序,枚举 \(d\),而 \(d\mid\gcd(i,j)\Leftrightarrow d\mid i\land d\mid j\),因此式子变成

\[\sum_{d=1}^{\min(n,m)}\mu(d)\sum_{i=1}^{n}[d\mid i]\sum_{j=1}^m[d\mid j]=\sum_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\frac{n}{d}\right\rfloor\left\lfloor\frac{m}{d}\right\rfloor \]

线性筛筛出莫比乌斯函数,预处理前缀和,整除分块即可。视 \(a,b\) 同阶,时间复杂度为 \(\mathcal{O}\left(a+T\sqrt{\frac{a}{d}}\right)\)

Luogu P2522 [HAOI2011] Problem b

二维差分,然后就是 Luogu P3455

Luogu P4450 双亲数

还是 Luogu P3455

线性筛积性函数

对于一个积性函数 \(f\),若我们能由 \(f(p^k)\) 快速算出 \(f(p^{k+1})\),则可以使用线性筛把 \(f(1),f(2),\cdots,f(n)\) 筛出来。

\(x\) 的质因数分解为 \(\prod_{i=1}^kp_i^{c_i}\),其中 \(p_1<p_2<\cdots<p_k\),我们记录 \(low_x=p_1^{c_1}\)。线性筛时,我们会把一个数 \(x\) 表示成 \(p_1y\) 的形式,分类讨论:

  • \(p_1\not\mid y\),则 \(p_1\perp y\),因此 \(f(x)=f(p_1)f(y)\)
  • \(p_1\mid y\),考虑把 \(low_y\) 除掉。若 \(low_y=y\),说明 \(x\)\(p_1\) 的若干次幂,我们由 \(f(y)\) 推出 \(f(x)\) 即可;否则我们有 \(f(x)=f\left(\frac{y}{low_y}\right)f(p_1low_y)\)

SPOJ 5971 LCMSUM - LCM Sum

\(\operatorname{lcm}\) 转化成 \(\gcd\),再变换求和顺序,得到

\[\begin{align*} &\sum_{i=1}^n\operatorname{lcm}(i,n)\\ =&n\sum_{i=1}^n\frac{i}{\gcd(i,n)}\\ =&n\sum_{i=1}^ni\sum_{d\mid n}\frac{1}{d}[\gcd(i,n)=d]\\ =&n\sum_{d\mid n}\frac{1}{d}\sum_{i=1}^ni[\gcd(i,n)=d]\\ =&n\sum_{d\mid n}\sum_{i=1}^{\frac{n}{d}}i\left[\gcd\left(i,\frac{n}{d}\right)=1\right]\\ =&n\sum_{d\mid n}\sum_{i=1}^di[\gcd(i,d)=1]\\ \end{align*} \]

\(g(n)=\sum_{i=1}^ni[\gcd(i,n)=1]\),还是老套路展开 \(\varepsilon(\gcd(i,n))\),再变换求和顺序:

\[\begin{align*} &g(n)\\ =&\sum_{i=1}^ni\sum_{d\mid\gcd(i,n)}\mu(d)\\ =&\sum_{d\mid n}\mu(d)d\sum_{i=1}^{\frac{n}{d}}i\\ =&\sum_{d\mid n}\mu(d)d\frac{\frac{n}{d}\left(\frac{n}{d}+1\right)}{2}\\ =&\frac{n}{2}\sum_{d\mid n}\mu(d)\left(\frac{n}{d}+1\right) \end{align*} \]

\(\mu*\operatorname{id}=\varphi\)\(\mu*1=\varepsilon\),可以得到上式又等于 \(\frac{n}{2}(\varphi(n)+\varepsilon(n))\)。当 \(n=1\) 时,\(g(n)=1\) 需要特判;当 \(n\neq 1\) 时,\(\epsilon(n)=0\),则 \(g(n)=\frac{n\varphi(n)}{2}\)。注意到 \(g\) 是积性函数,令 \(f(n)=\sum_{d\mid n}g(d)\),则 \(f=g*1\) 也是积性函数,可以线性筛预处理:

\[f(p^{k+1})=f(p^k)+p^{k+1}\varphi(p^k)=f(p^k)+p^{k+1}(p-1)p^k \]

我们所求即为 \(\frac{n(f(n)+1)}{2}\)。时间复杂度 \(\mathcal{O}(n+T)\)

Luogu P1891 疯狂 LCM

双倍经验 SPOJ 5971

SPOJ 4168 SQFREE

莫比乌斯函数作为容斥系数的经典应用。容斥计算,答案就是偶数个质数相乘的平方的倍数,减去奇数个质数相乘的平方的倍数,也就是

\[\sum_{i=1}^{\sqrt{n}}\mu(i)\left\lfloor\frac{n}{i^2}\right\rfloor \]

也可以利用经典结论:\(\mu^2(n)=\sum_{d^2\mid n}\mu(d)\)

证明:若 \(n\) 不含平方因子,则结论显然正确。否则考虑 \(n\) 的质因数分解 \(\prod_{i=1}^kp_i^{c_i}\),构造 \(n'=\prod_{i=1}^kp_i^{\lfloor\frac{c_i}{2}\rfloor}\),容易发现枚举 \(d^2\mid n\) 等价于枚举 \(d\mid n'\),因此右边的式子等于 \(0\)证毕。

于是答案就是

\[\sum_{i=1}^{n}\sum_{d^2\mid n}\mu(d)=\sum_{d=1}^{\sqrt{n}}\mu(d)\left\lfloor\frac{n}{d^2}\right\rfloor \]

相当于从推式子的角度验证了容斥的正确性。

线性筛筛出莫比乌斯函数,暴力计算即可。时间复杂度 \(\mathcal{O}(T\sqrt{n})\)

Luogu P4318 完全平方数

二分答案 + SPOJ 4168 即可。

Luogu P2257 YY的GCD

考虑枚举 \(\gcd(x,y)=p\)

\[\begin{align*} &\sum_{p\in\mathbb{P}}\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=p]\\ =&\sum_{p\in\mathbb{P}}\sum_{i=1}^{\frac{n}{p}}\sum_{j=1}^{\frac{m}{p}}[\gcd(i,j)=1]\\ =&\sum_{p\in\mathbb{P}}\sum_{i=1}^{\frac{n}{p}}\sum_{j=1}^{\frac{m}{p}}\sum_{d\mid\gcd(i,j)}\mu(d)\\ =&\sum_{p\in\mathbb{P}}\sum_{d=1}^{\min\left(\frac{n}{p},\frac{m}{p}\right)}\mu(d)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor \end{align*} \]

感觉不是很好推了。遇到下整除分母出现两个变量,需要用到一个 trick:枚举 \(T=pd\),则上式变为

\[\sum_{T=1}^{\min(n,m)}\left\lfloor\frac{n}{T}\right\rfloor\left\lfloor\frac{m}{T}\right\rfloor\sum_{p\in\mathbb{P},p\mid T}\mu\left(\frac{T}{p}\right) \]

这么做是考虑把整除提前,留下形如 \(\sum\mu(x)\) 的式子方便预处理。

\(f(n)=\sum_{p\in\mathbb{P},p\mid n}\mu\left(\frac{n}{p}\right)\),考虑用线性筛将其筛出,我们还是把 \(x\) 分解成 \(p_1y\),分类讨论:

  • \(p_1\not\mid y\):此时满足 \(p\mid x\) 的质数 \(p\) 要么是 \(p_1\),要么是 \(y\) 的质因子。对于前者,显然值为 \(\mu(y)\);对于后者,\(\mu\left(p_1\frac{y}{p}\right)=-\mu\left(\frac{y}{p}\right)\),总和即为 \(-f(y)\)。因此此时 \(f(x)=\mu(y)-f(y)\)
  • \(p_1\mid y\)\(p\) 还是只有两种取值:\(p_1\)\(y\) 的质因子。前者依然值为 \(\mu(y)\);对于后者,此时 \(p_1\frac{y}{p}\) 有平方因子,\(\mu\) 值都是 \(0\)。因此此时 \(f(x)=\mu(y)\)

预处理前缀和整除分块即可,时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)

SPOJ 4491 PGCD - Primes in GCD Table

双倍经验 Luogu P2257

Luogu P1829 [国家集训队] Crash的数字表格 / JZPTAB

还是 \(\operatorname{lcm}\) 化成 \(\gcd\),然后枚举 \(\gcd\)

\[\begin{align*} &\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)\\ =&\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{\gcd(i,j)}\\ =&\sum_{d=1}^{\min(n,m)}\frac{1}{d}\sum_{i=1}^n\sum_{j=1}^mij[\gcd(i,j)=d]\\ =&\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}ij[\gcd(i,j)=1] \end{align*} \]

\(g(n,m)=\sum_{i=1}^n\sum_{j=1}^mij[\gcd(i,j)=1]\),套莫反:

\[\begin{align*} &g(n,m)\\ =&\sum_{i=1}^n\sum_{j=1}^mij\sum_{d\mid\gcd(i,j)}\mu(d)\\ =&\sum_{d=1}^{\min(n,m)}\mu(d)d^2\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}ij\\ =&\sum_{d=1}^{\min(n,m)}\mu(d)d^2sum\left(\left\lfloor\frac{n}{d}\right\rfloor\right)sum\left(\left\lfloor\frac{m}{d}\right\rfloor\right) \end{align*} \]

其中我们令 \(sum(n)=\frac{n(n+1)}{2}\)。预处理 \(\mu(n)n^2\) 的前缀和,整除分块即可计算 \(g(n,m)\)

回到原式:

\[\begin{align*} &\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}ij[\gcd(i,j)=1]\\ =&\sum_{d=1}^{\min(n,m)}dg\left(\left\lfloor\frac{n}{d}\right\rfloor,\left\lfloor\frac{m}{d}\right\rfloor\right) \end{align*} \]

同样整除分块计算即可。时间复杂度 \(\mathcal{O}(\min(n,m))\)

SPOJ 8099 TABLE - Crash´s number table

双倍经验 Luogu P1829

AtCoder ABC400 C 2^a b^2

枚举 \(a\),累加 \(b\) 的个数,直接算会算重,让 \(a\) 成为最大的 \(a\) 使得 \(2^ab^2=x\) 即可,这等价于 \(b\) 是奇数,所以答案就是

\[\sum_{a=1}^{\log_2n}\left\lfloor\frac{\sqrt{\frac{n}{a}}+1}{2}\right\rfloor \]

时间复杂度 \(\mathcal{O}(\log{n})\)。要开 long double。

AtCoder ABC400 E Ringo's Favorite Numbers 3

题目的条件等价于这个数是一个完全平方数且恰好有 \(2\) 个本质不同的质因子。线性筛预处理每个数的最小质因子,然后直接枚举 \(i=1\sim 10^6\),对 \(i^2\) 分解质因数判断是否符合条件,询问时二分即可。时间复杂度 \(\mathcal{O}(\sqrt{a}+q\log{\sqrt{a}})\)

\(\text{2025/4/6}\)

Luogu T594651 C god

题意:\(n\) 个战士,第 \(i\) 个战士战力值为 \(a_i\)。接下来进行 \(n-1\) 轮投票,每一轮投票,每个战士会把票投给和他战力值差距最大的战士,若战力值差距相同,则投给编号最大的战士。每一轮得票最多的战士会被淘汰,若票数相同,则编号最大的战士会被淘汰。求最后剩下来的战士的编号。\(1\leq n\leq 10^6\)

排序,每一轮二分找出最大的 \(\leq\left\lfloor\frac{\min+\max}{2}\right\rfloor\) 的位置 \(p\),则 \(i\leq p\) 的战士投给 \(\max\)\(i>p\) 的战士投给 \(\min\),判断两者哪个票数最多即可。时间复杂度 \(\mathcal{O}(n\log{n})\)

Luogu T594652 D distance

题意:给定平面上的 \(n\) 个点 \(p_i\),第 \(i\) 个点的坐标为 \((x_i,y_i)\)。定义一次跳跃为从 \((x,y)\) 跳到 \((x+1,y),(x-1,y),(x,y+1),(x,y-1)\) 中的一个。再定义两点间的距离为它们之间的最小跳跃次数,若无法到达则为 \(0\)。求 \(\sum_{i=1}^{n-1}\sum_{j=i+1}^n\operatorname{dist}(p_i,p_j)\)\(2\leq n\leq 2\times 10^5\)

容易发现只有 \(x_i+y_i\) 奇偶性相同的点才能互相到达,所以按照这个分成两组点,对每组点分别计算。发现算的是切比雪夫距离,令 \((x,y)\rightarrow(x+y,x-y)\),转化为曼哈顿距离,然后排序之后处理前缀和即可 \(\mathcal{O}(n)\) 计算。时间复杂度为 \(\mathcal{O}(n\log{n})\),瓶颈在于排序。

Luogu P5903 【模板】树上 K 级祖先

\(\mathcal{O}(n)\) 长链剖分,\(\mathcal{O}(n\log{n})\) 倍增预处理树上 \(2^k\) 级祖先。每次询问,先跳到 \(x\)\(h=2^{\lfloor\log_2 k\rfloor}\) 级祖先 \(y\),即 \(k\) 的最高位对应的 \(2\) 次幂级祖先。考虑 \(y\) 所在的长度为 \(len\) 的长链,于是

\[len\geq h>\frac{k}{2}>k-h \]

我们预处理出从每条长链的链顶向上走 \(i\) 步能到达的点 \(up_{u,i}\),以及向下走 \(i\) 步能到达的点 \(down_{u,i}\),其中 \(0\leq i\leq len\),这部分复杂度是 \(\mathcal{O}(n)\) 的。然后我们从 \(y\) 跳到其链顶 \(top_y\),然后令 \(k\leftarrow k-(dep_x-dep_{top_y})\)。若 \(k\geq 0\),则答案就是 \(up_{top_y,k}\),否则若 \(k<0\),则答案就是 \(down_{top_y,-k}\)。根据前面的不等式,容易证明 \(x\)\(k\) 级祖先跳不出这条从 \(top_y\) 向上向下各走 \(len\) 步的链。

时间复杂度是 \(\mathcal{O}(n\log{n})-\mathcal{O}(1)\) 的。预处理部分瓶颈在于树上倍增。

\(\text{2025/4/8}\)

Luogu P3520 [POI 2011] SMI-Garbage

之前做过但有点忘了,重做一下。考虑 \(s=t\) 的边,它们需要被经过偶数次,我们任取两个经过它的简单环,如果将该边删去,那完全可以把这两个简单环合并成一个,一定更优。于是只需要保留 \(s\neq t\) 的边,DFS 找环,用栈记录方案。加上当前弧优化,时间复杂度为 \(\mathcal{O}(n+m)\)

Codeforces 1009F Dominant Indices

\(f_{u,i}\) 表示 \(sub_u\) 中和 \(u\) 的距离为 \(i\) 的节点个数。转移显然:

\[f_{u,i}=\sum_{v\in son_u}f_{v,i-1} \]

对于有维度和深度相关的树形 DP,考虑长链剖分优化。我们先让 \(f_{u,i}\) 继承它的长儿子的 DP 数组,然后再遍历所有轻儿子暴力合并。注意继承 DP 数组的部分需要用指针实现,让 \(f_u\)\(f_{lson_u}\) 共用一片内存,然后对应偏移即可。注意到暴力合并的过程等价于对每条长链在其链顶的父亲节点处合并一次,总时间复杂度是 \(\mathcal{O}(n)\) 的。

Luogu P3565 [POI 2014] HOT-Hotels

\(f_{u,i}\) 表示 \(sub_u\)\(\operatorname{dist}(u,v)=i\) 的点 \(v\) 的个数,\(g_{u,i}\) 表示 \(x,y\in sub_u\) 满足

\[\operatorname{dist}(x,\operatorname{lca}(x,y))=\operatorname{dist}(y,\operatorname{lca}(x,y))=\operatorname{dist}(\operatorname{lca}(x,y),u)+i \]

\((x,y)\) 的个数。列出转移方程如下,其中 \(v\in son_u\)

\[f_{u,i}\leftarrow f_{u,i}+f_{v,i-1}\\ g_{u,i}\leftarrow g_{u,i}+g_{v,i+1}+f_{u,i}f_{v,i-1} \]

考虑在三个点的 \(\operatorname{lca}\) 处统计答案,于是得到

\[ans\leftarrow ans+f_{u,j}g_{v,j+1}+g_{u,j+1}f_{v,j} \]

时间复杂度为 \(\mathcal{O}(n^2)\)

Luogu P5904 [POI 2014] HOT-Hotels 加强版

Luogu P3565 的基础上直接长链剖分优化就是 \(\mathcal{O}(n)\) 的。给指针分配两倍空间是因为 \(g_u\) 是倒开的,可能访问到负数索引,需要防止错误访问到前面的数据。

STL nth_element

传入一个基准元素 \(a_k\),对序列进行排列使得 \(\forall 1\leq i<k\leq j\leq n,a_i\leq a_j\)

Luogu P10641 BZOJ3252 攻略

考虑贪心,每次选择一条从根节点到叶子节点的价值和最大的链,累加进答案里,然后把链上的点权清空。我们定义路径权值为其上的点权和,进行长链剖分,然后观察到上面的贪心等价于选择权值前 \(k\) 大的长链。利用 STL 的 nth_element 即可做到 \(\mathcal{O}(n)\)

\(\text{2025/4/10}\)

Luogu P1121 环状最大两段子段和

挺巧妙的题,可惜做过类似套路。先考虑不存在跨环的子段,那就是序列上的问题,预处理前后缀 \(\mathcal{O}(n)\) 枚举断点。如果存在跨环的子段,则没被选中的两个子段不跨环,改成选最小就行了。第二种情况需要特判,全是负数时不能全选,和只有一个非负数时不能除了这个非负数都选。存在断环成链然后复制到末尾的做法,简单限制一下长度即可。时间复杂度 \(\mathcal{O}(n)\)

Luogu P1091 [NOIP 2004 提高组] 合唱队形

\(\mathcal{O}(n^2)\) 预处理前后缀 LIS/LDS 然后 \(\mathcal{O}(n)\) 枚举分割点。

Luogu P1280 尼克的任务

把所有区间按左端点排序,对时间轴倒序 DP 即可。时间复杂度 \(\mathcal{O}(k\log{k}+n)\)

Luogu P1130 红牌

直接 \(\mathcal{O}(nm)\) DP。

Luogu P2196 [NOIP 1996 提高组] 挖地雷

\(\mathcal{O}(n^2)\) DP 再记录一下方案。

Luogu P4933 大师

\(f_{i,j}\) 表示以 \(a_i\) 结尾的公差为 \(j\) 的等差数列个数,随便 \(\mathcal{O}(nV)\) DP。

AtCoder chokudai S001 H LIS

LIS 板子。可以树状数组优化,或者令 \(f_{i}\) 表示长度为 \(i\) 的 LIS 的最小末尾元素,二分更新。时间复杂度都是 \(\mathcal{O}(n\log{n})\) 的。

\(\text{2025/4/11}\)

Luogu P3591 [POI 2015] ODW

根号分治,取阈值 \(T=\sqrt{n}\)\(\mathcal{O}(n\sqrt{n})\) 预处理 \(v_{u,i}(1\leq i\leq T)\) 表示从 \(u\) 开始一直向上跳 \(i\) 步的权值和。如果 \(c>T\) 就暴力跳,如果 \(c\leq T\) 就利用预处理数组计算答案。这样子暴力跳部分是 \(\mathcal{O}(n\sqrt{n}\log{n})\) 的,长链剖分 \(\mathcal{O}(1)\)\(k\) 级祖先就可以把 \(\log\) 去掉。时间复杂度为 \(\mathcal{O}(n\sqrt{n})\)

DFS 序求 LCA

之前学过这玩意儿,学虚树的时候发现实现起来常数太大了,遂重新学习。

先给出结论:对于两点 \(u,v(u\neq v)\),钦定 \(dfn_u<dfn_v\),则 \(\operatorname{lca}(u,v)\)\([dfn_u+1,dfn_v]\) 中深度最小的任意节点的父亲。

证明:若 \(u\)\(v\) 的祖先,则 \([dfn_u+1,dfn_v]\) 就是 \(sub_u\) 中所有 \(dfn_u<dfn\leq dfn_v\) 的节点,这这些点中深度最小的点必然是 \(u\) 的某个儿子,此时结论正确;如果 \(u\) 不是 \(v\) 的祖先,考察 \(d=\operatorname{lca}(u,v)\),则 \([dfn_u+1,dfn_v]\) 就是 \(sub_d\) 中所有 \(dfn_u<dfn\leq dfn_v\) 的节点,由于 \(u,v\)\(d\) 的不同子树中,这些点一定包含了 \(d\)\(v\) 方向的儿子,且它必然是深度最小的点之一,结论依然正确。证毕。

于是我们在 DFS 序上用 ST 表维护关于深度的 \(\operatorname{argmin}\) 即可做到 \(\mathcal{O}(n\log{n})-\mathcal{O}(1)\) 地回答 LCA。

但是这样常数很大。存在方法不用记录每个节点的父亲节点和深度,具体来说,我们在 ST 表记录对应的父亲节点,比较时直接比较它们的 DFS 序大小。

正确性证明:该过程等价于对于任意的 \(u',v'\),满足 \(dfn_u<dfn_{u'}\leq dfn_{v'}<dfn_v\),证明 \(d=\operatorname{lca}(u,v)\)\(\operatorname{lca}(u,v'),\operatorname{lca}(u',v)\)\(dfn\) 较小的一个。若 \(u\)\(v\) 的祖先正确性显然。否则根据 DFS 序的性质,\(\operatorname{lca}(u,v')\) 只可能是 \(u\)\(d\)\(\operatorname{lca}(u',v)\) 只可能是 \(v\)\(d\),而 \(dfn_{u'}\leq dfn_{v'}\) 又说明这两个 LCA 不能恰好一个是 \(u\),一个是 \(v\),因此这两个 LCA 中至少有一个为 \(d\)证毕。

Luogu P2495 [SDOI2011] 消耗战

虚树板子题。令 \(f_u\) 表示令 \(u\)\(sub_u\) 中的询问点不连通的最小代价,\(v_u\) 表示 \(u\) 是否为询问点,则

\[f_u= \begin{cases} +\infty&v_u=1\\ \displaystyle\sum_{v\in son_u}\min(f_v,w_{u,v})&v_u=0 \end{cases} \]

朴素做是 \(\mathcal{O}(nm)\) 的,无法承受。建出虚树,把 \(w_{u,v}\) 设为 \(\operatorname{path}(u,v)\) 上的最小边权,这个倍增求解,然后直接树形 DP 就行了。时间复杂度 \(\mathcal{O}((n+\sum k)\log{n})\)

\(\text{2025/4/12}\)

Luogu P6156 简单题

还是经典结论,\(f(n)=\mu^2(n)\),代入推式子:

\[\begin{align*} &\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\mu^2(\gcd(i,j))\gcd(i,j)\\ =&\sum_{d=1}^n\mu^2(d)d^{k+1}\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{n}{d}}(i+j)^k[\gcd(i,j)=1]\\ =&\sum_{d=1}^n\mu^2(d)d^{k+1}\sum_{t=1}^{\frac{n}{d}}\mu(t)t^k\sum_{i=1}^{\frac{n}{td}}\sum_{j=1}^{\frac{n}{td}}(i+j)^k \end{align*} \]

\(sum(n)=\sum_{i=1}^n\sum_{j=1}^n(i+j)^k\),式子变为

\[\sum_{d=1}^n\mu^2(d)d^{k+1}\sum_{t=1}^{\frac{n}{d}}\mu(t)t^ksum\left(\left\lfloor\frac{n}{td}\right\rfloor\right) \]

下整除分母出现两个变量,考虑经典套路,令 \(T=td\),则式子变为

\[\sum_{T=1}^nT^ksum\left(\left\lfloor\frac{n}{T}\right\rfloor\right)\sum_{d\mid T}\mu^2(d)d\mu\left(\frac{T}{d}\right) \]

内层的求和就是 \(f=(\mu^2\times\operatorname{id})*\mu\),是积性函数,考虑线性筛将其筛出。讨论 \(f(p^k)\) 的取值:

  • \(k=1\)\(f(p)=\mu(p)+\mu^2(p)p=p-1\)
  • \(k=2\)\(f(p^2)=\mu^2(p)p\mu(p)=-p\)
  • \(k\geq 3\):显然 \(d\)\(\frac{p^k}{d}\) 中至少有一个包含平方因子,因此此时 \(f(p^k)=0\)

根据上述讨论直接筛就行了。

再来考虑如何快速求出 \(sum(n)\)。令 \(g(n)=\sum_{i=1}^ni^k,h(n)=\sum_{i=1}^ng(n)\),可以得到

\[\begin{align*} sum(n)&=\sum_{i=1}^ng(i+n)-g(i)\\ &=\sum_{i=n+1}^{2n}g(i)-\sum_{i=1}^ng(i)\\ &=h(2n)-h(n)-h(n)\\ &=h(2n)-2h(n) \end{align*} \]

\(i^k\) 可以线性筛筛出:对于质数暴力快速幂,其他数直接乘起来,时间复杂度 \(\mathcal{O}(n\frac{\log{k}}{\ln{n}})\approx\mathcal{O}(n)\)。然后做两次前缀和就能算出 \(g(n)\)\(h(n)\),再预处理 \(T^kf(T)\) 的前缀和,整除分块就做完了。时间复杂度 \(\mathcal{O}(n)\)

Luogu P6222 「P6156 简单题」加强版

双倍经验 Luogu P6156

Luogu P10105 [GDKOI2023 提高组] 游戏

首先有经典结论,三点两两间的路径恰好交于一点 \(p\),且三点位于点 \(p\) 的不同子树中。我们容易列出关于 \(\operatorname{dist}(p,u),\operatorname{dist}(p,v),\operatorname{dist}(p,w)\) 的方程:

\[\begin{cases} \operatorname{dist}(p,u)+\operatorname{dist}(p,v)=x\\ \operatorname{dist}(p,u)+\operatorname{dist}(p,w)=y\\ \operatorname{dist}(p,v)+\operatorname{dist}(p,w)=z \end{cases} \]

解得

\[\begin{cases} \operatorname{dist}(p,u)=\frac{x+y-z}{2}\\ \operatorname{dist}(p,v)=\frac{x-y+z}{2}\\ \operatorname{dist}(p,w)=\frac{-x+y+z}{2}\\ \end{cases} \]

考虑枚举这个点 \(p\) 后怎么做:我们需要 \(u,v,w\) 放到 \(p\) 的不同的子树里,那直接贪心,将距离 \(p\) 最大的点放到以 \(p\) 为根深度最大的子树中,距离次大、次次大同理。

于是我们对于每个点,预处理出以它为根,深度最大/次大/次次大的子树深度,这个可以树形 DP 做。令 \(f_{u,0/1/2}\) 表示以 \(u\) 为根时深度最大/次大/次次大的子树深度,\(g_{u,0/1/2}\) 表示对应的叶子,\(b_{u,0/1/2}\) 表示是从哪个子树转移过来的。转移相当于每次把 \(f_{u,0/1/2}\)\(f_{v,0}\) 放在一起排序,取前 \(3\) 大,写一个类似冒泡排序的东西就行了。然后类似做换根 DP。

那么现在我们需要找到一个满足要求的点 \(p\),满足 \(f_{p,0}\geq a,f_{p,1}\geq b,f_{p,2}\geq c\),看上去是三维偏序,但是我们可以对 \(f_{p,2}\) 这一维直接贪心,变成找到一个点 \(p\),满足 \(f_{p,0}\geq a,f_{p,1}\geq b\)\(f_{p,2}\) 最大,这样就是二维偏序了,扫描线,用树状数组维护后缀 \(\max\)\(\operatorname{argmax}\) 即可。

最后就是找到点 \(p\) 后,需要找出对应的 \(x,y,z\),简单分类讨论后树上倍增即可。

\(n,q\) 同阶,时间复杂度为 \(\mathcal{O}(n\log{n})\)

AtCoder ABC401 E Reachable Set

显然与 \([1,k]\) 中点直连的点构成的集合就是我们要删除的点集,这部分每次加入一个点就遍历所有出边更新点集大小即可。再考虑怎么判无解:把所有 \(1\leq u<v\leq k\) 的边 \((u,v)\) 连起来,若 \([1,k]\) 不连通则无解。这部分并查集维护即可。时间复杂度 \(\mathcal{O}(m\log{n}+n)\)\(\mathcal{O}(m\alpha(n)+n)\)

AtCoder ABC401 F Add One Edge 3

赛时做出来了,可惜时间不够没调出来。

\(f_{1/2,u}\) 表示第 \(1/2\) 棵树中,从点 \(u\) 出发能到达的最远距离,那么直径有两种可能:两棵树直径的最大值 \(d\),或者 \(f_{1,i}+f_{2,j}+1\)。对 \(f_2\) 排序,枚举 \(i\),二分出最靠右的满足 \(f_{2,j}\leq d-f_{1,i}-1\) 的端点 \(p\),预处理 \(f_2\) 的前缀和即可快速计算。时间复杂度为 \(\mathcal{O}(n\log{n})\)

\(\text{2025/4/13}\)

AtCoder ABC401 D Logical Filling

勾史细节题。首先把所有与 o 相邻的 ? 换成 .,并计算出 \(k\) 减掉原串中的 o 个数的结果 \(k'\),如果 \(k'=0\) 需要特判全部填成 .。现在的串 \(T\) 包含了若干个由 . 包围的极长 ? 块,一个长度为 \(len\) 的块最多可以塞 \(\left\lfloor\frac{len+1}{2}\right\rfloor\)o,计算出能塞的 ? 的个数的最大值 \(mx\),若 \(mx=k'\),则所有块都取到最大值,长度为奇数的块填法确定,长度为偶数不确定;否则此时 \(mx>k'\),我们随意取一个所有块达到最大值的串,显然其中每个位置都可以被扣成 .,因此这种情况全部无法确定。然后最后再次把所有与 o 相邻的 ? 换成 . 即可。时间复杂度 \(\mathcal{O}(n)\)

\(\text{2025/4/15}\)

Luogu P12147 【MX-X11-T1】「蓬莱人形 Round 1」仅此而已,就已经足够了

赛时被干废了。

\(b=\lfloor\log_2(n)\rfloor\),特判 \(k>b\),此时 \(f(x)=2^k\),答案为 \(2^k(n+1)\)

接下来,考虑 \(+2^k\) 能带来什么影响。显然它影响不了低 \(k-1\) 位,因此我们每 \(2^k\) 个数分成一组,它们的 \(f\) 值都一样,最后会有一些余项,它们的和即为 \(f(n)((n\bmod{2^k})+1)\),我们把它加到答案上。

注意到由于低 \(k-1\) 位被忽略掉了,此时问题转化成了 \(k=0\) 的形式。我们继续挖掘 \(+2^k\) 的性质,考虑进位,发现相当于从第 \(k\) 位往高位找到第一个 \(0\) 的位置 \(p\),把 \([k,p]\) 中的位翻转,其它位保持不变,因此 \(f(x)=\sum_{i=k}^p2^i\)。于是我们枚举 \(p\) 然后计数即可,计数部分就是简单的不等式了。

时间复杂度 \(\mathcal{O}(T\log{n})\)

\(\text{2025/4/18}\)

Luogu P3233 [HNOI2014] 世界树

建出虚树。通过两次 DFS,容易对于每个点 \(u\) 求出管辖它的关键点 \(g_u\)。先对每个虚树上的点算贡献,考虑一个点 \(u\),我们遍历它的虚树上的儿子 \(v\),把 \(u\)\(v\) 方向上的儿子的子树扣掉,剩下的 \(sub_u\) 内的点贡献给 \(g_u\)。再考虑虚树相邻两点路径上的点的贡献,我们倍增求解出深度最小的 \(p\) 使得 \(p\)\(g_v\) 管辖而不是 \(g_u\),令 \(s\)\(u\)\(v\) 方向上的儿子,那么 \(g_u\) 就获得了 \(sz_s-sz_p\) 的贡献,\(g_v\) 获得了 \(sz_p-sz_y\) 的贡献。时间复杂度 \(\mathcal{O}((n+\sum k)\log{n})\)

\(\text{2025/4/19}\)

Luogu P7843 「C.E.L.U-03」布尔

显然无解当且仅当区间内存在形如 \(u=v\land x\neq y\) 的限制,预处理前缀和 \(s_i=\sum_{j=1}^i[u_j=v_j\land x_j\neq y_j]\),则当 \(s_r>s_{l-1}\) 时无解。

观察到给出的限制是无向限制,所以可以扩展域并查集维护。

划段可以直接贪心,即对于当前位置 \(x\),我们找到最小的使得 \([x,y]\) 不合法的 \(y\),把 \([x,y-1]\) 划作一段,再令 \(x\leftarrow y\)。暴力跳无法承受,考虑倍增优化,预处理出 \(g_{i,j}\) 表示从 \(i\) 开始跳 \(2^j\) 次跳到的位置,那么就可以做到单次询问 \(\mathcal{O}(\log{m})\)。对于边界问题,我们把第 \(m+1\) 条限制搞成一个不合法限制即可。

问题转化为求出 \(f_i\) 表示最小\(j\) 使得 \([i,j]\) 不合法。注意到 \(f_i\) 单调不减,反证容易证明。于是套路地考虑决策单调性二分,也即整体二分:\(\operatorname{solve}(l,r,L,R)\) 表示 \(\forall i\in[l,r],f_i\in[L,R]\),令 \(mid=\left\lfloor\frac{l+r}{2}\right\rfloor\),我们求出 \(f_{mid}\) 后递归下去。我们从 \(mid\) 开始暴力加边,若 \(u\)\(\lnot u\) 连通则无解。当然,这样暴力加边时间复杂度是错的,那么我们再次套路地考虑用可撤销并查集回滚。可以发现,如果在 \(\operatorname{solve}\) 之前保证 \([r+1,L-1]\) 中的限制都被加入,我们就可以做到只增不删。具体来说,我们先依次加入 \([mid,\min(r,L-1)]\) 中的边,再依次加入 \([\max(mid,L),R]\) 中的边,加到不合法为止时记录答案。然后我们按需撤销并查集即可。

时间复杂度 \(\mathcal{O}(n\log{n}\log{m}+(m+q)\log{m})\)

Luogu P4103 [HEOI2014] 大工程

建出虚树。令 \(cnt_u\) 表示 \(sub_u\) 内的关键点的个数,\(mx_u/mn_u\) 表示 \(u\)\(sub_u\) 内的关键点的最远/最近距离,每次转移 \((u,v,w)\) 时,用 \(mn_u+mn_v+w\) 更新 \(ans_2\),用 \(mx_u+mx_v+w\) 更新 \(ans_3\),再用 \(mn_v+w\)\(mx_v+w\) 分别更新 \(mn_u\)\(mx_v\)。对于 \(ans_1\),我们令 \(ans_1\leftarrow ans_1+sz_v(k-sz_v)w\)。时间复杂度 \(\mathcal{O}((n+\sum k)\log{n})\)

Luogu P12246 电 van

先求出初始时的答案:预处理前缀 \(\text{v}\) 和后缀 \(\text{n}\) 的个数,答案就是 \(\sum_{s_i=\text{a}}pre_{i-1}suf_{i+1}\)

再来考虑交换操作的影响。容易发现,当且仅当 \(\{s_x,s_{x+1}\}=\{\text{v},\text{a}\}\)\(\{s_x,s_{x+1}\}=\{\text{a},\text{n}\}\) 时答案会改变。当 \(s_x=\text{v}\land s_{x+1}=\text{a}\) 时,\(ans\leftarrow ans-suf_{x+2}\),其他情况同理。同时我们也要对应更新 \(pre\)\(suf\),直接讨论即可。时间复杂度 \(\mathcal{O}(n+m)\)

Luogu P12247 跳舞机

考虑 DP。令 \(f_i\) 表示 \([1,i]\) 时刻内能获得的最大兴奋值。转移考虑可以这一局不玩,或者枚举所有可以在 \([i-k+1,i]\) 玩一局跳舞机的玩家,即

\[f_i=\max\left(f_{i-1},\max_{l_j\leq i-k+1\land r_j\geq i}\{f_{i-k}+w_j\}\right) \]

扫描线优化即可。视 \(n,m\) 同阶,时间复杂度 \(\mathcal{O}(n\log{n})\)

AtCoder ABC402C Dislike Foods

考虑倒序处理,变成每次讨厌一道料理,那么对每一道料理存储包含它的所有菜肴的编号,直接遍历处理即可。时间复杂度 \(\mathcal{O}(\sum k_i)\)

AtCoder ABC402D Line Crossing

正难则反,求出平行的直线的总数,令 \(f(x)=x-[x>n+1]n\),容易注意到平行的两条直线 \((x_1,y_1),(x_2,y_2)\) 满足 \(f(x_1+y_1)=f(x_2+y_2)\),开桶计数即可。

P2197 【模板】Nim 游戏

板子。先手必胜当且仅当 \(\oplus_{i=1}^n a_i\neq 0\)

证明咕咕咕。

\(\text{2025/4/24}\)

Codeforces 786B Legacy

P6348 [PA 2011] Journeys

\(\text{2025/4/25}\)

P5025 [SNOI2017] 炸弹

\(\text{2025/4/29}\)

Codeforces 1842C Tenzing and Balls

考虑 DP。令 \(f_i\) 表示 \(a[1,i]\) 中最多能删除的球的数量,容易列出转移方程:

\[\begin{align*} f_i&=\max(f_{i-1},\max_{a_j=a_i}\{i-j+1+f_{j-1}\})\\ &=\max(f_{i-1},i+1+\max_{a_j=a_i}\{f_{j-1}-j\}) \end{align*} \]

开桶即可 \(\mathcal{O}(n)\) 解决。

P4735 最大异或和

可持久化 Trie 板子。容易转化成最大化 \(sum_n\oplus x\oplus sum_{p}(l-1\leq p\leq r-1)\)\(p\leq r-1\) 用可持久化即可保证,而对于 \(p\geq l-1\),令 \(end_u\) 为以 \(u\) 节点结尾的最大版本号,\(f_u\)\(sub_u\)\(end\) 的最大值,这个容易递归建树预处理出来,于是查询时添加上 \(f_u\geq l-1\) 的限制即可。

posted @ 2025-05-11 11:08  P2441M  阅读(16)  评论(0)    收藏  举报