🍕🏠🌋 当前时间是:

 

2025.6

[Ynoi2008] stcm

考虑链分治,重链上的点的答案容易得出,但是要想办法递归下去。

现在需要把除去一个轻子树以外的所有其他轻子树的结点加进栈来,可以分治地加入和撤销结点,复杂度是 2log 的。

把树剖换成全局平衡二叉树(重量平衡),就能分析到 1log 了。

另一种简单的做法是:直接对 dfn 序列分治,相当于每次询问刨去一个区间,而且这些区间只有不交和包含关系,可以直接做到 1log 次操作。

Generalized Insertion Sort

先考虑一条链的做法:插入排序,每次把当前序列头部的点插入到后面的正确位置,共不超过 \(n-1\) 次操作。

放到树上可以考虑一个叶子一个叶子删,但是这样每次需要把一个叶子结点转到根,总的复杂度是错的。

继续类比链的做法,把当前树的所有一度链叶子找出来,把它们包含的点使用插入排序排好,相当于要把这些点依次转到根,每次操作深度最深的即可 \(O(n)\) 次操作做一轮。

还可以发现删掉一度链叶子,树的叶子结点数量砍半,最后就是 \(O(n\log n)\) 次操作。

20250602模拟赛T1

一个位置初始值大于 3 无解。

猜测一下可以忽略操作顺序任意操作,发现全 1 就爆了(可能 111111 会被误判为合法)。

就要求连续的 1 不能凭空操作。

从前往后 dp 套贪心即可,我的状态数有 15 个,把矩乘卡卡常即可。

正解是观察到合法的连续段形态只有 \(O(1)\) 种,贪心地划分。

20250602模拟赛T3

相关内容:tb5 分治。

考虑 \(t\) 个以 \(x\) 为中心,大小为 \(k\) 的邻域,能把整棵树划分成 \(O(\min(n,t^2))\) 个等价类。

考虑对操作序列分治,初始认为每个点自己是一个等价类,每个分治区间内就只有 \(O(\min(n,(r-l+1)^2))\) 个等价类。

分治 \([l,r]\) 时,向左区间 \([l,mid]\) 递归前,把只考虑 \([l,mid]\) 的操作等价的等价类合并,到叶子结点就对 \(O(1)\) 个等价类统计答案和打标记,回溯时把考虑 \([l,mid]\) 操作等价的等价类分裂成考虑 \([l,r]\) 操作等价的等价类,并把标记下传。向右侧递归时同理。

如此操作就总共会涉及 \(O(\sum\limits_{l,r}\min(n,(r-l+1)^2))=O(m\sqrt{n})\) 次等价类分裂和合并操作。

下面来考虑在本题的背景下如何维护等价类。

考虑集合哈希,对一个邻域内的点异或上一个随机数,这样两个权值相同的点就可以判定在一个等价类里面。

也就是要支持 \(O(m\log m)\) 次邻域异或和 \(O(m\sqrt{n})\) 次单点查询。

直接点分树和树状数组维护是 \(O(m\log m\log^2 n+m\sqrt{n}\log^2 n)\) 的,有点太慢了。

希望把查询变得快一点:把树状数组换成分块,由于每次修改在点分树上跳子树大小翻倍,所以一次修改的复杂度是 \(O(\sum \sqrt{\dfrac{n}{2^i}})=O(\sqrt{n})\) 的,单次询问是 \(O(\log n)\) 的。

最后复杂度是 \(O(m\sqrt{n}(\log n+\log m))\) 的,卡常之后可以通过。

QOJ 6504

相邻相同字符相消的处理方法我见过两种。

第一种是哈希+二分合并两个序列,放在这个题上可以线段树套可持久化平衡树,但是时间空间复杂度都是 2log 的,不能适用。

第二种是观察到相消的两个字符初始下标奇偶性不同,所以可以给每种字符设计一种只有交换律没有结合律的运算,给奇偶位置分别赋正逆运算,最后 check 这些运算合并起来是不是单位运算。

具体到这个题使用第二种方法,可以对 3 种字符各随机一个小矩阵,需要这个矩阵存在逆元,把奇偶位置分别赋正逆的矩阵,使用线段树维护一个结点三种偏移量的矩阵积,查询时 check 区间矩阵积是不是单位矩阵即可。时间复杂度是 1log。

CF1458D Flip and Reverse

操作要求区间内 01 个数相等,可以想到给 01 分别赋 +1 和 -1 的权值,求这个串的前缀和 \(s\),就要求操作区间 \([l,r]\) 满足 \(s_{l-1}=s_r\)

一个想法是对于 \(0\leq i< n\),连无向边 \((s_i,s_{i+1})\),那么原串相当于这个图从 0 到 \(s_n\) 的一条欧拉路径。

另一个想法是猜测这个图的欧拉路径都可以被这样的操作生成出来。

为了证明这个结论,先考察这个操作相当于在欧拉路径上干什么。

手玩一下发现,这相当于把一个环走法翻转。

那么考虑两条欧拉路径的第一个不同的边,一条走的是 \((x,x-1)\),另一条是 \((x,x+1)\),那么在必然还存在没有走过的 \((x-1,x)\)\((x+1,x)\) 各一条,不然两条欧拉路径就至少有一条走不回 \(x\) 了。

当第一条路径此后第一次走 \((x+1,x)\) 时,把这段环翻转,就把两条欧拉路径第一个不同的边的位置向后推了,进而归纳就可以证明。

最后这个题就是求一个字典序最小的欧拉路径即可。

不太懂建图和欧拉路径是如何想象到的。

[IOI 2018] meetings

容易想到一个区间 dp 的暴力:一个区间要么终点是最大值的位置,要么在其两侧,在左侧则右侧的所有位置对答案的贡献是最大值。

尝试去直接优化这个算法。

首先可以将一个询问拆成三部分:终点是最大值位置、在最大值左侧和在最大值右侧。

这样看上去状态就少了一些(笛卡尔树上区间长度之和),而且第二部分 reverse 之后做一遍就是第三部分了,这个 trick 似乎有不少用途。

以右侧为例,把询问离线,在笛卡尔树上区间 dp。

假设当前考虑到区间 \([l,r]\),最大值位置是 \(mid\),那么有 \(\forall mid< i\leq r,dp_{l,i}=\min(dp_{mid+1,i}+(mid-l+1)\times a_{mid},dp_{l,mid-1}+(i-mid+1)\times a_{mid})\)

观察到第一项增速不超过 \(a_{mid}\),而第二项增速是 \(a_{mid}\),所以一定是一个前缀做第二种转移,剩下的后缀做第一种。

使用线段树维护即可,每次二分出修改的位置,需要支持区间加一次函数和区间推平。

复杂度可以 1log。

DAG 容斥

考虑如何数 DAG。

可以发现每次删掉所有零度点,这样生成一个 DAG 的过程是唯一的。

极大零入度点集是不好刻画的,但是可以容斥。

\(f_{S}\) 表示 \(S\) 集合恰好是当前零度点集合的方案数,\(g_{S}\) 是钦定 \(S\) 集合都是零度点的方案数。

那么有 \(g_{S}=\sum\limits_{S\subseteq T}f_{T}\)

子集反演得到 \(f_{S}=\sum\limits_{S\subseteq T}g_{T}(-1)^{|T|-|S|}\)

那么

\(\begin{align}&\sum\limits_{T\subseteq S,T\neq \emptyset}f_{T}\\&=\sum\limits_{T\subseteq S,T\neq \emptyset}\sum\limits_{T\subseteq P} g_{P}(-1)^{|P|-|S|}\\&=\sum\limits_{P\subseteq S,P\neq \emptyset}g_{P}(-1)^{|P|}\sum\limits_{T\subseteq P,T\neq \emptyset} (-1)^{|T|}\\&=\sum\limits_{P\subseteq S,P\neq \emptyset}g_{P}(-1)^{|P|+1}\end{align}\)

大部分涉及数 DAG 的题目应该都需要这样的容斥。

相关的题有:主旋律、重塑时光、岁月

P4229 某位歌姬的故事

如果值域是 2,可以简单 dp,做到 1log。

对于原问题,可以推导一些性质:

根据每个序列位置被限制的最大值的最小值,分成本质不同的几小段 \([L_i,R_i,a_i]\)

如果一个限制 \([l_i,r_i,m_i]\) 内有一小段 \([L_i,R_i,a_i]\) 被要求的最大值 \(a_i<m_i\),那这一段就是不能要的。

再观察一下发现 \([l_i,r_i,m_i]\) 内的小段被要求的最大值都是不超过 \(m_i\) 的,所以对于 \([l_i,r_i]\),只需要限制其内部有至少一个 \(a_i=m_i\) 的小段被选即可。

每种类型的小段是独立的,分别做值域为 2 的 dp 即可。

20250624模拟赛 T2

对长为 \(n\),值域为 \([1,m]\) 的所有序列 \(a\),求出 \(\prod\limits_{a} \text{lcm}(a_1,a_2,\cdots ,a_n)^{\gcd(a_1,a_2,\cdots,a_n)}\)
\(m,n\leq 3\times 10^7\)

好标准的数论题。

对指数莫反得到 \(\prod\limits_{p}\prod\limits_{d} \prod\limits_{a,dp\mid a_i} \text{lcm}(a_1,a_2,\cdots,a_n)^{d\mu(p)}\)

\(d\)\(p\) 的乘积总是一起出现所以枚举它(实际上就是做了 \(\varphi\) 反演):\(\prod\limits_{T} \prod\limits_{a,T\mid a_i} \text{lcm}(a_1,a_2,\cdots,a_n)^{\sum\limits_{p} \mu(p)\frac{T}{p}}\)

问题就变成对于每个 \(m\) 的块筛处(\(\lfloor\dfrac{m}{T}\rfloor\))求 \(\prod\limits_{a,T\mid a_i} \text{lcm}(a_1,a_2,\cdots,a_n)\)

做 min-max 容斥,变成枚举大小为 \(i\) 的集合 \(\prod\limits_{i>0} \prod\limits_{a,T\mid a_j} \gcd(a_1,a_2,\cdots,a_i)^{\binom{n}{i}(-1)^{i-1}\lfloor\frac{m}{T}\rfloor^{n-i}}\)

\(T\) 提出来变成 \(\prod\limits_{i>0} \prod\limits_{a,a_j\leq \lfloor\frac{m}{T}\rfloor} (T\gcd(a_1,a_2,\cdots,a_i))^{\binom{n}{i}(-1)^{i-1}\lfloor\frac{m}{T}\rfloor^{n-i}}\)

然后来处理第一部分: \(\prod\limits_{i>0} \prod\limits_{a,a_j\leq \lfloor\frac{m}{T}\rfloor} T^{\binom{n}{i}(-1)^{i-1}\lfloor\frac{m}{T}\rfloor^{n-i}}=\prod\limits_{i} T^{\binom{n}{i}(-1)^{i-1}\lfloor\frac{m}{T}\rfloor^{n}}\)

用二项式定理化成 \(T^{\lfloor\frac{m}{T}\rfloor^n}\),可以 \(O(m\log n)\) 算。

然后先来处理第二部分:\(\prod\limits_{i>0} \prod\limits_{a,a_j\leq \lfloor\frac{m}{T}\rfloor} \gcd(a_1,a_2,\cdots,a_i)=\prod\limits_{i>0}\prod\limits_{p}\prod\limits_{d} (d^{\mu(p)\lfloor\frac{m}{dpT}\rfloor^i})^{\binom{n}{i}(-1)^{i-1}\lfloor\frac{m}{T}\rfloor^{n-i}}\)

依然是用二项式定理合并一下指数,变成 \(\prod\limits_{p}\prod\limits_{d} d^{\mu(p)(\lfloor\frac{m}{T}\rfloor^n-(\lfloor\frac{m}{T}\rfloor-\lfloor\frac{m}{dpT}\rfloor)^n)}\)

套三层整除分块,复杂度是 \(O(m^{0.875}\log n)\) 的。(事实上常数很大,整除分块的计算量在这道题的数据范围下比 \(m\) 还大)

考虑如何给两部分去 \(\log\):第一部分不太容易,第二部分可以推一下发现只需要求 \(i!^k\) 和其逆元,而且 \(i\) 只有 \(O(\sqrt{m})\) 种取值,可以分四段光速幂预处理,做到 \(O(\text{mod}^{0.25}\sqrt{m})\) 预处理 \(O(1)\) 查询,但是这个查询常数有点大。

问题还是第一部分处理不了。

出题人题解给的做法是分段打表 \(\prod T^{\varphi(T)}\)

更麻烦一点的做法是使用离散对数,可以直接解决所有问题,需要使用 \(O(\dfrac{\text{mod}^{0.75}}{\sqrt{\log \text{mod}}})\) 预处理,\(O(\log \text{mod})\) 询问的离散对数才能较快通过。

最后复杂度是 \(O(m)\) 和离散对数预处理。

20250620模拟赛T2

每次询问树上编号在一个区间内的点选不超过 \(k\) 个点构成的虚树大小边权和的最大值。
\(k\leq 100\)

先来考虑全局怎么做:长链剖分,选最长的 \(k-1\) 条链。

感受一下这个东西类似树的直径,是能合并的,数据结构维护这些选出来的点即可。

CF1416F

要最终连出一个基环树森林,一个观察是如果一个点周围存在小于它的点,可以直接把它向该点连边,其答案就是它们的点权差。

剩下的就是有一些点一定要在环上。

还需要观察到环一定是偶环,所以可以拆成若干个二元环,这样就是匹配了。

跑上下界网络流即可。

CF1844G

超神秘构造题,感觉不太是人能想到的。

现在是有若干个方程 \(d_i+d_{i+1}-2d_{lca(i,i+1)}=x_i\)

考虑对两边取模,模 \(2^k\),那么发现只需要知道所有 \(d\)\(2^{k-1}\) 的值就能解出模 \(2^k\) 的值了。

ZJOI 2019 麻将

笑点解析:碰见这个题前一天我有一把可以六巡九莲宝灯听牌但我没有识别出来,把 9 打了出去。

我们尝试求出有多少种大小为 \(i\) 的牌的集合存在一个子集胡牌,然后通过一些简单容斥就能算出答案。

来考虑如何判定一套牌是不是胡的:这个问题似乎没有简单的贪心判定的方法,但是容易设计出 dp 来判定。

具体的,假设考虑前 \(p\) 张牌,可以对于每个可达状态 \((i,j,k,t)\) 表示长为 2 的插头(\(p-2,p-1\))有 \(i\) 个,长为 1 的插头有 \(j\) 个,总共已经有 \(k\) 个面子,\(t\) 个对子,把该状态转移到其他状态。

这样假设有 \(S\) 个可达状态,就可以 \(O(nS)\) 判定一套牌能不能胡(\(n\) 是牌的种类数)。

下面来考虑算方案。

可以很暴力地记录 \(2^S\) 种判定 dp 数组以及当前牌集合的大小。

这看上去状态数超级大,但是可以感受到最内层有用的状态很少,而且外层 dp 能达到的状态有一定关联度,本质不同的应该也不会很多。

尝试对内层 dp 爆搜状态,加入剪枝。

比如:对子超过一个就要求其他维全是 0、两维插头数量都不超过 4-面子数等。

我能搜出来只有 90 种状态,而外层只有 2459 种。

最后复杂度就是 \(O(n^2T)\),其中 \(T=2459\)

20250628模拟赛T1

关键性质:假设 \(s_1=0\),那么对于 \(i\ge 2\),有 \(s_i=[a_i=0]\)

考虑一种判定:对于一个位置 \(x\),要求 \(s_{[1,a_x]}=s_{[x,x+a_x-1]}\)\(s_{a_x+1}\neq s_{x+a_x}\)

把这些条件写成哈希的方程,每条限制随一个数作为权值,然后把贡献拆到每个数即可,复杂度线性。

20250604模拟赛 T1

快进到给一棵树,求一个拓扑序 \(p\),满足 \(\sum ip_i\) 最小。

这个是典题 color a tree,但是我不会这个 trick。

考虑全局最小值,它的父亲被选之后它一定会被立即选,所以可以尝试把它其父亲合并成一个点。

假设一个点有一个一次函数的贡献和点的大小 \((k,b,x)\),exchange argument 发现可以按照 \(\dfrac{x}{k}\) 排序。

这样用数据结构维护全局最小值并不断合并即可。

赛时写了 \(O(n^2)\) 的 dp 并加了些基于精度的剪枝通过了。

转置原理

对于一个线性算法(矩阵)\(A\),如果能对于任意输入向量 \(a\) 求出输出向量 \(b=Aa\),那么我们可以以几乎相同的复杂度解决线性算法 \(A^T\)

主要想法是给 \(A\) 分解成 \(E_{1}E_{2}\cdots E_{k}\),也就是一些方便转置的简单的矩阵的乘积(例如初等矩阵),然后直接倒过来跑 \(E_{k}^T E_{k-1}^T\cdots E_{2}^T E_{1}^T\) 即可。

一些线性代数理论证明,对于任意的 \(A\),都可以通过一些简单变换使其能分解成若干初等矩阵的乘积。

多项式多点求值

给定 \(n\) 次多项式 \(f\) 和若干位置 \(a\),对于每个 \(a_i\) 求出 \(\sum f_ja_i^j\)

考虑将多点求值描述成线性算法:

\(f\) 为输入向量,那么就要乘上矩阵 \(A_{i,j}=a_{j}^i\) 得到输出向量,即 \(v_j\sum f_i a_{j}^i\)

给这个式子转置得到 \(w_j=\sum f_i a_{i}^{j}\),考虑解决这个转置问题:

不妨求出 \(w\) 的生成函数 \(W(x)=\sum\limits_{j} x^j \sum\limits_{i} f_i a_{i}^j\)

\(W(x)=\sum\limits_{i} \dfrac{f_i}{1-a_ix}\)

可以分治 ntt 维护分子分母解决这个问题。

假设分治区间是 \([l,r]\),左边的答案是 \(\dfrac{Q_L}{P_L}\),右边的答案是 \(\dfrac{Q_R}{P_R}\),那么本区间的答案就是 \(\dfrac{P}{Q}=\dfrac{P_LQ_R+P_RQ_L}{P_LP_R}\)

最后求出 \(P\times Q^{-1}\) 即可。

考虑将这个算法转置回多点求值。

由于 \(a\) 视作算法的常量参数,所以所有 \(P\) 都是已经确定的,可以预处理出来。

对于 \(Q\gets Q+P_LQ_R\) 的操作,写成矩阵就是 \([Q,Q_R]\times \begin{bmatrix} 1 & 0 \\ P_L & 1 \end{bmatrix}\),转置之后得到 \(\begin{bmatrix} 1 & P_L \\ 0 & 1 \end{bmatrix}\),也就是 \(Q_R \gets Q_R+P_L\times ^T Q\),其中 \(\times^T\) 是卷积的转置操作,也就是差卷积(可以通过写出卷积的矩阵说明)。

那么沿分治树从上往下做这个算法,就能在叶子结点的常数项处得到点值。

posted @ 2025-06-22 18:46  zzafanti  阅读(21)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end