杂题选写4
树上随机游走
向父亲游走的期望距离
设 \(f_u\) 为 \(u\to fa_u\) 的期望距离。
那么根据定义,有
有边界为叶子满足 \(f_u=w(u,fa_u)\)。
当 \(w=1\) 时,有 \(f_u=deg_u+\sum\limits_{v\in Son(u)}f_v=2sz_u-1\)。
后面那个等号是因为除了自己连向父亲的边只贡献了一次其他边都贡献了两次。
向孩子游走的期望距离
设 \(g_u\) 为 \(fa_u\to u\) 的期望距离。
那么根据定义,有
边界为 \(g_{rt}=0\)。
P3412 仓鼠找sugar II
令终点为 \(E\),起点为 \(u\),向父亲游走的期望距离为 \(f_u\)。
那么答案就是 \(\frac{\sum\limits_{\operatorname{root}(T)=E}\sum\limits_{u=1}^nsz_uf_u}{n^2}\)。
换个根,做完了。
P5024 [NOIP2018 提高组] 保卫王国
首先一眼动态 dp,然后不会了,因为每次直接修改点权要修改一路向上的答案。
考虑怎么去避免这个事情,事实上可以轻重链分治,记录轻儿子的和维护重链。
那我们就可以跳 \(O(\log n)\) 次重链和轻链,就可以了。
这样单次修改复杂度是 \(O(k^3n\log^2n)\) 的,其中 \(k=2\)。
注意询问的时候单点修改的顺序!!
P4859 已经没有什么好害怕的了
令 \(f_k\) 为恰好有 \(k\) 个 \(a_i>b_i\),\(g_k\) 为钦定有 \(k\) 个,则 \(g_k=\sum\limits_{i=k}^n\binom ikf_i\)。
那么 \(f_k=\sum\limits_{i=k}^n(-1)^{i-k}\binom ikg_i\)。
考虑计算 \(g_i\),令 \(dp_{i,j}\) 为前 \(i\) 个里钦定了 \(j\) 个的方案数。转移是简单的。
那么就做完了。
P4705 玩游戏
可以得到 \(nm\mathbb E=\sum\limits_{i=1}^n\sum\limits_{j=1}^m(a_i+b_j)^k\)。
稍微拆一下式子,得到 \(nm\mathbb E=k!\sum\limits_{k_1+k_2=k}\left(\sum\limits_{i=1}^n\frac{a_i^{k_1}}{k_1!}\right)\left(\sum\limits_{i=1}^m\frac{b_i^{k_2}}{k_2!}\right)\)。
令 \(A(x)=\sum\limits_{i=1}^n\sum\limits_{k\geqslant 0}\frac{a_i^k}{k!}x^k,B(x)=\sum\limits_{i=1}^m\sum\limits_{k\geqslant 0}\frac{b_i^k}{k!}x^k\),可得 \(mn\mathbb E=k\)。
那么现在要考虑怎么快速去计算 \(A,B\)。
以 \(A\) 为例,令 \(f_i=i![x^i]A=\sum\limits_{i=1}^na_i^k\),可得 \(F(x)=\sum\limits_{i=1}^n\frac1{1-f_ix}\)。
令 \(G(x)=\sum\limits_{i=1}^n\ln(1-f_ix)\),可得 \(G'(x)=\sum\limits_{i=1}^n\frac{-f_i}{1-f_ix}\),于是 \(F(x)=n+\sum\limits_{i=1}^n\frac{f_ix}{1-f_ix}=n-G'(x)x\)。
现在考虑计算 \(G(x)\),发现 \(G(x)=\ln\prod\limits_{i=1}^n(1-f_ix)\),使用分治乘计算即可。
复杂度貌似是 \(O(n\log^2n)\) 的。
CF802L Send the Fool Further! (hard)
令 \(f_u\) 表示从 \(u\) 开始随机游走的期望步数,可以得到
是一个典型的自己含父亲和叶子的式子,不能直接递推,需要树上高消。
考虑从下往上做,令 \(f_u=k_uf_{fa_u}+b_u\),考虑求解 \(k_u,b_u\)。
那么就可以求解了。
注意到叶子的 \(k=b=0\),那么就可以递推了。
对于根节点,可得
发现只要令 \(w(u,fa_u)=0,f_{fa_u}=0\) 就可以做到形式上的一致。
那么就做完了,复杂度 \(O(n)\),但要带上求逆的复杂度。
信息熵
定义式:\(H(X)=-\sum\limits_{x\in X}P(x)\lg P(x)\)。
信息熵描述了信息的混乱度,其中信息熵越大越混乱不确定性越高,我们就要尝试去减小信息熵,询问时尝试去询问信息熵差量最大的方式。
P9477 [_-0 C] 猜数
很神秘的交互题。
我们记录 \(P(X=i)\) 表示答案为 \(i\) 的概率,这是容易动态维护的。
现在要考虑利用这个去合理询问。结合一般的猜数游戏的朴素二分,我们可以联想到在概率密度上的中点询问,类似于这种二分。
接下来估算询问次数,需要用到信息熵。
初始时 \(H=-\log\frac1n\)。整个过程 \(\Delta H=\log\frac1n\)。
假设询问 \(x\),询问前 \(P(X<x)=P(x>x)=\frac12\),询问后一个变为 \(p\),一个变为 \(1-p\),信息熵从 \(-\log\frac12\) 变成 \(-k\log k-(1-k)\log(1-k)\)。
因此有 \(q\approx\frac{\log\frac1n}{(-k\log k-(1-k)\log(1-k))-(-\log\frac12)}\),代入 \(k=0.49\) 后经计算符合询问次数范围。
P5264 多项式三角函数
注意到 \(e^{ix}=\cos x+i\sin x,e^{-ix}=\cos x-i\sin x\)。
因此有 \(\sin x=\frac{e^{ix}-e^{-ix}}{2i},\cos x=\frac{e^{ix}+e^{-ix}}2\)。
注意到虚数单位 \(i\) 在模意义为 \(i^4=1\Rightarrow i=\omega_4\Rightarrow i=(g^{p-1})^{\frac14}\)。
然后就做完了。
P4517 [JSOI2018] 防御网络
考虑拆贡献。首先对于每个连通块分别计算。
考虑对树边和环边分开考虑,对于树边,方案数是容易计算的,也就是两边都有点的方案数。
对于一个环,发现朴素的方法难以处理,考虑先预处理出每一个点上有多少种方案挂点。
然后先钦定一个起点和环上一个方向,类似于断环为链。
发现答案是环长减去最大相隔距离。
考虑一个 dp,\(f_{i,j,k}\) 表示起点为 \(i\) 终点为 \(j\) 最大相隔距离为 \(k\) 的方案数,那么状态转移和答案统计都变得容易了。
复杂度 \(O(n^4)\),卡卡可过。
甚至不用卡,跑得飞快。
也可以前缀和优化,做到 \(O(n^3)\)。
P9120 [春季测试 2023] 密码锁
分类讨论。
- \(k=1\)
此时求的就是极差。
- \(k=2\)
答案上界为全局最大值减去全局最小值,那么考虑将这两个值放在两行,比如小的放上面,那么剩下所有列都这么做,可以发现是最优的。
- \(k=3\)
考虑二分答案,问题转化为判断 \(m\) 是否合法。
先把全局最大值 \(mx\) 放在第一行。枚举全局最小值 \(mn\) 在哪一行。
对于一个数 \(x\),能把它放在最大值行当且仅当 \(x\geqslant mx-m\),能把它放在最小值行当且仅当 \(x\leqslant mn+m\)。
因此可以先枚举每一个列,判断是否存在一种方案使得一个放最大行一个放最小行。如果没有就直接不合法了。
那么对于还没有限制的那一行,每一列都会有若干个备选项。将这些值放在数轴上并根据所属列染色,问题转化为是否存在一个区间 \(len=m\) 满足覆盖了所有颜色。
发现这样不是很好做,考虑变成枚举每一种颜色筛选区间左端点。
具体地,我们可以处理出每一种颜色,如果要覆盖这种颜色,左端点需要在一个区间或者几个区间的并内。
考虑在数轴上区间 \(+1\),那么我们只需要查询最终是否存在点的值为颜色数即可。
这可以差分处理出来。
复杂度 \(O((n+V)\log V)\)。
- \(k=4\)
和 \(k=3\) 类似,但是变成了有若干颜色矩形,判断是否有一个点被所有种类矩形覆盖。
考虑使用扫描线,然后线段树维护,这是比较简单的。
但是注意到同一种矩形会有多个,难以处理。
但注意到同种矩形最多有 \(4\) 个,直接暴力容斥求出并。
复杂度 \(O((n+V)\log^2V)\)。
然后你就被卡常了。
注意到求交的时候右端点的取值集合永远是 \(O(n)\) 的,因此可以离散化,降成 \(O((n+V)\log n\log V)\)。
然后你就被卡常了。
注意到可以把区间加差分成前缀加,然后把同一位置的加合并,这样就可以减少常数,快了不止两倍,就过了。
CF1592F1 Alice and Recoloring 1
注意到操作二可以差分成两次操作一,操作三可以差分成两次操作一,都是不劣的。
那么现在只有两种操作了,分别是包含 \((1,1),c=1\) 和包含 \((n,m),c=3\)。
考虑令 \(b_{i,j}=a_{i,j}\oplus a_{i+1,j}\oplus a_{i,j+1}\oplus a_{i+1,j+1}\),那么把 \(a\) 归零与把 \(b\) 归零等价,此时一次操作变成单点修改了。
操作一修改 \(b_{x,y},c=1\)。操作四修改 \(b_{x-1,y-1},b_{x-1,m},b_{n,y-1},b_{n,m},c=3\)。
看起来操作四的性价比更高。但事实上会发现操作四更优当且仅当四个数全都是 \(1\),而最多操作四一次后 \(b_{n,m}=0\)。因此操作四最多一次。
枚举哪一个位置进行操作四即可。此时问题解决,复杂度 \(O(mn)\)。
CF1592F2 Alice and Recoloring 2
发现操作二和操作三还是假的。
还是一样的构造 \(b\)。
考虑什么时候会用操作四。
首先不会出现同一行或者同一列使用多于一次操作四,因为会变成用 \(4\) 的代价修改四个点,可以转化为用四次操作一。
其次,发现只有除了 \(b_{n,m}\) 以外的其他三个数都是 \(1\) 的时候才会进行操作四,因为如果有 \(0\) 不优于使用操作一。对于 \(b_{n,m}\) 来说是否操作四对它是不劣的。
由于每行每列最多一个,就变成二分图匹配问题了。
复杂度 \(O(n^2\sqrt n)\)。
AT_arc104_c [ARC104C] Fair Elevator
脑电波题。
考虑判断是否合法,发现在值域上分成了若干个长度为偶数的段,每个段都形如左边的点有一个唯一的右边的点匹配。
那么直接判断能否这么合法划分就可以了。
复杂度 \(O(n^3)\)。
AT_arc104_e [ARC104E] Random LIS
发现 \(n\) 充分小,因此可以考虑各种做法。
比如枚举 \(n\) 个数的大小关系,然后变成选数问题,发现就是 APIO2016 划艇,套上去就好了。
AT_arc104_f [ARC104F] Visibility Sequence
发现 \(n\) 比较小,考虑使用区间 dp。
首先 \(a_i\) 太大是没有用的,所以可以对 \(n\) 取 \(\min\)。
注意到最大值位置不同则导出序列一定不同,若有多个最大值取最右边的。
考虑建出笛卡尔树,发现笛卡尔树的结构和导出序列一一对应。
令 \(f_{l,r,x}\) 表示区间 \([l,r]\) 作为一棵子树,根节点值不超过 \(x\) 的不同树形态方案数。
枚举根的编号,可以得到 \(f_{l,k-1,\min(x,a_k)}f_{k+1,r,\min(x,a_k)-1}\to f_{l,r,x}\)。
复杂度 \(O(n^4)\)。
P8340 [AHOI2022] 山河重整
找出 \([1,n]\) 的所有子集 \(S\) 满足 \(\forall i\in[1,n],\exist T\subseteq S,\sum\limits_{x\in T}x=i\)。
先考虑一个高复杂度的做法。
考虑从小到大加入数。
首先,任意时刻可以拼出的数一定恰好是一个前缀。
证明考虑归纳法,选 \(1\) 的时候显然,那么在前 \(i\) 个数拼出 \([1,j]\) 时,考虑选不选 \(i+1\)。
当且仅当 \(i\neq j\) 时 \(i+1\) 可以不选,此时还是一个前缀 \([1,j]\)。
如果选 \(i+1\),变成前缀 \([1,j+i+1]\)。
此时已经可以直接 \(O(n^2)\) dp 求解了。
发现这个做法难以优化,考虑正难则反,计算不合法的方案数,然后容斥。
令 \(f_i\) 表示在 \([1,i]\) 中选子集,选出的子集拼出的数恰好为 \([1,i]\) 的方案数。发现选出的子集和必须是 \(i\)。
那么钦定 \(i+1\) 不选,答案就是 \(2^n-\sum\limits_{i=0}^{n-1}f_i2^{n-i-1}\)。
考虑求 \(f_i\),使用容斥,令 \(g_i\) 表示在 \([1,i]\) 中选出子集,子集和为 \(i\) 的方案数。
枚举能拼出来的最长前缀,那么 \(f_i=g_i-\sum\limits_{j=0}^{i-1}f_jh(j,i)\),其中转移系数 \(h(j,i)\) 表示用 \([j+2,i]\) 的数拼出 \(j-i\) 这个和的方案数。
考虑求解 \(g,h\),那么就做完了。
对于 \(g\),就是经典的互异拆分数的方案数。
考虑计算这个东西,发现最多选 \(2\sqrt i\) 的数就会到达上界,这启示我们思考 \(O(n\sqrt n)\) 的做法。
联想到以前做过的拆分数方法,发现可以变成两种操作,在序列末尾加一个 \(0\) 和全局 \(+1\)。
放到互异上,其实就是 \(+1\) 的次数是 \(O(\sqrt n)\) 的级别的。
于是我们可以枚举 \(+1\) 时的序列长度,做一个完全背包。注意序列长度的变化量最多为 \(1\),也就是要钦定至少选了一次。
那么这样就可以在 \(O(n\sqrt n)\) 内求出 \(g\) 了。
对于 \(h\),难搞啊。
考虑不显式的计算 \(h_i=\sum\limits_{j=0}^{i-1}f_jh(j,i)\),类似于 \(g\) 的转移直接转移 \(f\)。
考虑到 \(h\) 的转移是一个线性变换,因此可以修改初值之后和 \(g\) 类似地转移。
此处的正确性来源于一个无名 trick,我愿称之为整体 dp。考虑以下简单问题:
现在有一个 \(f\) 和变换 \(f_i=\sum\limits_{j=1}^if_i\)。
现在有 \(q\) 次询问,每次给定一个 \(x\),初始 \(f_i=[i=x]\),然后从小到大依次进行变换,求 \(q\) 次变换后 \(f_n\) 的和。
考虑离线 \(q\) 次询问,遇到一个 \(x\) 就 \(f_x\gets f_x+1\),然后再一起做就好了。
因为前缀和是一个线性变换。
观察这个转移,发现 \(f,h\) 缠缠绵绵互相转移,不能直接做。
发现有 \(f_j\to h_{j+(j+2)i}\),因此可以类似 cdq 分治,先算左边再贡献到右边这样子算。
复杂度 \(O(n\sqrt n)\)。
AT_abc134_f [ABC134F] Permutation Oddness
发现绝对值难以处理,考虑拆贡献。
发现就是 \(i\to p_i\) 的贡献为 \(|i-p_i|\),考虑从这个角度入手,拆贡献。
钦定上面匹配下面。
令 \(f_{i,j,k}\) 表示前 \(i\) 个数上面仍然有 \(j\) 个未匹配(一定在 \(i\) 右侧匹配到,且下面也一定有 \(j\) 个未匹配,且一定在 \(i\) 右侧匹配到),当前和 减去 上面未匹配位置的下标和 减去 下面未匹配位置的下标和 为 \(k\) 的方案数。
考虑决策 \(i\),\(i\) 的上面和下面的匹配方案,分类讨论:
- 自己和自己匹配,\(\times 1 \to f_{i+1,j,k}\)。
- 上面向左,下面向左,\(\times j^2\to f_{i+1,j-1,k+2i}\).
- 上面向左,下面向右,\(\times j\to f_{i+1,j,k}\)。
- 上面向右,下面向左,\(\times j\to f_{i+1,j,k}\)。
- 上面向右,下面向右,\(\times 1\to f_{i+1,j+1,k-2i}\)。
复杂度 \(O(n^4)\)。
AT_agc008_e [AGC008E] Next or Nextnext
考虑一个 \(p\) 环能生成怎么样的 \(a\) 图,应该是一些特殊的基环树。
一个奇环,若 \(a_i=p_i\) 则不变,若 \(a_i=p_{p_i}\) 则同构,否则基环树。
一个偶环,若 \(a_i=p_i\) 则不变,若 \(a_i=p_{p_i}\) 则拆成两个长度减半的环,否则基环树。
那么可以枚举每种形态的 \(a\) 图反推合法的 \(p\) 的方案数。
环的情况是简单的,涉及到一些合并,稍微有点细节。
基环树有些困难。
首先这些基环树拿掉环之后一定是若干条链,且每条链接入环的点各不相同。
其次可以画图发现,若一条链长为 \(l_1\),上一个接入点距离当前接入点长为 \(l_2\),那么贡献就是 \(\begin{cases}2,&l_1<l_2,\\1,&l_1=l_2\\0,&l_1>l_2\end{cases}\)。
那么做完了。
AT_agc007_f [AGC007F] Shik and Copying String
首先需要 \(S,T\) 的位置匹配,可以直接倒着扫 \(T\) 找 \(S\) 最右边可以匹配的位置。
那我们可以拿出一些限制极紧的匹配,然后这些匹配可以写成若干段区间,每次可以左端点跳。
发现这个东西可以二分答案优化,那么就做完了。
复杂度 \(O(n\log n)\)。
AT_agc008_f [AGC008F] Black Radius
先考虑所有点都可以选的情况,考虑什么情况不会计重。
设 \(f(u,d)\) 表示选择 \(u\) 距离不超过 \(d\) 的点集。我们先不考虑全集的贡献,最后加上即可。
考虑对于一种方案在 \(d\) 最小的 \(u\) 处统计贡献。
那么如果计重,一定会有几个方向顶到底。
比如 \(f(u,d)\) 和 \(f(v,d-1)\) 满足 \(dis(u,v)=1\),且 \(u\) 的所有除了 \(v\) 的子树中离 \(u\) 最远的点距离不超过 \(d-2\)。
并且 \(f(u,d)\) 不能覆盖全树,令 \(f\) 为最远距离,\(g\) 为次远距离,那么就有 \(d\in[0,\min(f_u-1,g_u+1)]\)。
那么如果有点不能被选呢?
那么就需要有一个可以选的点 \(v\),满足 \(u\) 和 \(v\) 会计重,那么就会有贡献。
那么 \(u\) 在 \(v\) 方向上需要顶到底,令 \(h_u\) 表示所有可选点所在子树最深点的深度的最小值。
那么 \(d\in[h_u,\min(f_u-1,g_u+1)]\)。
以上信息可以使用换根求出来。
那么就做完了。
CF1830C Hyperregular Bracket Strings
如果两个区间有交,就可以拆成三个无交的限制。
这启示我们要对位置进行分组,分到同一个组的需要为合法括号串。
那么分组唯一依据就是被覆盖的区间的集合。
这可以异或哈希做到。
那么就做完了。
CF1909G Pumping Lemma
首先求出两个串的 LCP 和 LCS,可以得到一个重叠的部分 \(s\)。
那么 \(y\) 一定是 \(s\) 的子串。
找出 \(s\) 在 \(T\) 中第一次出现的位置 \([l_1,r_1]\) 和最后一次的位置 \([l_2,r_2]\)。
那么 \(y\) 在 \([l_1,r_1]\) 中出现的位置和 \([l_2,r_2]\) 出现的位置应当相同,因为 \(r_2-r_1=m-n=(k-1)|y|\),画图便可观察到。
那么 \(|y|\) 就是 \([r_1+1,r_2]\) 的循环同构一个整周期。
找到最小整周期,枚举其倍数。由于起点共有 \(r_1-l_1+1-|y|+1\) 中不同的可能,因此贡献为 \(r_1-l_1+1-|y|+1\)。
复杂度 \(O(n)\)。
CF1682E Unordered Swaps
题目保证有解,那么对于同一连通块,输入进来的一定是一棵树。
考察一次交换合法的条件,发现当且仅当一条边连着的两个点只置换环指向的两个点分别在对方子树内。
那么我们去动态维护这个东西,发现每次交换后会有 \(O(1)\) 条边的状态发生改变,可以 \(O(\log n)\) 找到后维护。
复杂度 \(O(n\log n)\)。
P3349 [ZJOI2016] 小星星
首先原问题等价于给树上的节点编号枚举一个排列映射,使得相邻点映射后在图上连通。
有一种暴力,叫做 \(f_{u,j,S}\) 表示子树 \(u\) 且 \(p_u=j\) 且子树使用了编号集 \(S\) 的方案数。
然后复杂度 \(O(n^33^n)\) 上天了,因为要枚举子集类似背包合并。
但如果不考虑标号的事情那么复杂度直接变成 \(O(n^3)\) 飞快。
但是有一种反演,叫做子集反演。
令 \(f_{S}\) 为映射集合恰好为 \(S\) 的方案数,\(g_{S}\) 为映射集合包含于 \(S\) 的方案数。
容易得出 \(g_S=\sum\limits_{T\subseteq S}f_T \Leftrightarrow f_S=\sum\limits_{T\subseteq S}(-1)^{|S|-|T|}g_T\)。
于是我们可以做到 \(O(n^32^n)\)。
那么就做完了。
P3321 [SDOI2015] 序列统计
首先有 \(f_{i,j}\) 为 \(i\) 个数积为 \(j\) 的方案数。
会有转移 \(f_{i,j}=\sum\limits_{ab\equiv j}f_{i-1,a}g_{b}\),其中 \(g\) 为 \(g_i=[i\in S]\)。
发现这个转移没有优化的前途。
考虑倍增,可以有 \(f_{2i,j}=\sum\limits_{ab\equiv j}f_{i,a}f_{i,b}\),会快一些。
但还是没什么前途,因为下标是一个乘积。
发现 \(m\) 很小,考虑暴力找出一个原根 \(g\)。
有了 \(g\) 就可以求出离散对数了。
那么就可以改写成 \(f_{2i,j}=\sum\limits_{k+l\equiv j}f_{i,k}f_{i,l}\),这个就看起来很可以卷积,其中模数的 \(g=3\)。注意此处是对 \(m-1\) 取模。
由于循环卷积,那么 \(f_{2i}(j)=f_{i}^2(j)+f_{i}^2(i+(m-1))\)。
然后在边界的情况是类似的。
那么直接倍增也做完了,过程类似于快速幂。
原根
不知道为什么板子早就过了,但我还不会。
阶的定义:若 \(a^n\equiv 1\pmod m\) 存在最小正整数解 \(n\),则 \(a\) 模 \(m\) 的阶为 \(n\),记作 \(\delta_m(a)=n\)。
阶满足性质 \(a^{[0,\delta_m(a)-1]}\) 两两不同余。
原根的定义:若对于数 \(n\) 存在数 \(g\) 满足 \(\delta_n(g)=\varphi(n)\),则 \(g\) 为 \(n\) 的原根。
当 \(n\) 为质数时 \(g^{[0,\varphi(n)-1]}\) 会覆盖 \([1,n-1]\) 的每一个数。
首先,只有 \(2,4,p^k,2p^k(p>2,k>0)\) 这四类数拥有原根,证明太复杂所以略。
其次,若 \(n\) 有原根,那么原根的数量为 \(\varphi(\varphi(n))\),证明考虑结合以下内容。
同时,设最小的原根为 \(g\),那么其他的所有原根 \(g'\) 都可以表示成 \(g'=g^k,\gcd(k,\varphi(n))=1\)。
如果我们要找出一个最小的 \(g\),由于某些证明,\(g\) 的大小是 \(O(n^{\frac14})\) 级别左右,因此可以暴力找。
现在考虑怎么判断 \(g\) 为原根。
如果是原根,首先有 \(g^{\varphi(n)}=1\),同时 \(g^k\neq 1,0<k<\varphi(n)\)。
枚举 \(k\) 显然是不现实的。但由于某些很神秘的数学结论,我们秩序检验 \(\varphi(n)\) 的所有因子便可验证正确性。
进一步的,可以只检验 \(\frac{\varphi(n)}p,p\mid \varphi(n)\),因为倍数显然限制更强。
此时我们就拥有了 \(O(\log n)\) 的判断方法了。
那我们就可以 \(O(n^{\frac14}\log n)\) 找出最小原根,再 \(O(\varphi(n)\log\varphi(n))\) 找出所有原根。
P3723 [AH2017/HNOI2017] 礼物
设变化量为 \(x\)。
考虑拆贡献,可得 \(\sum\limits_{i=1}^n(a_i-b_i-x)^2=nx^2-2x\sum a+2x\sum b+\sum a^2+\sum b^2-2\sum ab\)。
发现关于 \(x\) 的函数的二次项和一次项是定值,可以直接求出最小值。
但是常数项有 \(\sum ab\) 不是定值,那么我们现在要求它的最大值。
令 \(c_i=a_{n-i+1}\),发现 \(\sum\limits_{i=1}^na_ib_i=\sum\limits_{i=1}^nc_{n-i+1}b_i\),是一个卷积的形式。
直接倍长之后做卷积就完了。
反正值域小,可以直接对 \(998244353>nm^2\) 取模,省事。
P4643 [国家集训队] 阿狸和桃子的游戏
貌似以前就听过,但是一直没做。
边权拆点权,排一遍序,贪心取最大,做完了。
不见得有多难啊,听说以前是黑的。
AT_agc013_e [AGC013E] Placing Squares
组合意义保平安。
有一个小学生都会的 dp 叫做 \(f_i=\sum\limits_{j\not\in S}f_j(j-i)^2\)。然后这没有任何优化的前途。
考虑平方的组合意义。
段与段之间放隔板,一些位置不能放隔板。
我们要在每一段里放一个黑球一个白球,位置可以相同。
令 \(f_{i,j}\) 为前 \(i\) 个位置,当前段放了 \(j\) 个球的权值和。
考虑转移,根据 \(i-1\) 与 \(i\) 之间能否放隔板分类讨论。
若不放隔板,则
- \(f_{i,0}\gets f_{i-1,0}\)
- \(f_{i,1}\gets f_{i-1,1}+2f_{i,0}\)
- \(f_{i,2}\gets f_{i-1,0}+f_{i-1,1}+f_{i-1,2}\)
若放隔板,则
- \(f_{i,0}\gets f_{i-1,2}\)
- \(f_{i,1}\gets 2f_{i-1,2}\)
- \(f_{i,2}\gets f_{i-1,2}\)
容易矩阵优化,瞎做就好了。
其实也有嗯推的做法,神奇的是代码写出来一模一样。
最小割树
可以快速求一张无向图两点之间的最小割。
首先有一个结论,\(n\) 个点的图上本质不同的最小割规模是 \(n-1\) 的,证明不见了。
依照这个结论,我们可以把原图等价于一棵最小割树,在树上做最小割,就变成一个路径最小值的典题了。
考虑怎么建出最小割树。
先找到两个点求出最小割。然后连边 \((u,v,s)\)。
此时,原图分为两部分 \(S,T\),分别递归建树。
因为这样一定能求出 \(n-1\) 个最小割,所以就对完了。
预处理复杂度 \(O(n^3m)\),实际卡不满。
P4173 残缺的字符串
有一手很牛逼的构造。
令 * 为 \(0\),构造函数 \(f(S,T)=\sum\limits_{i=1}^n(S_i-T_i)^2S_iT_i\)。
匹配当且仅当 \(f=0\)。
考虑构造卷积,可以翻转 \(S\),拆开得到 \(f=\sum\limits_{i=1}^nS_{n-i+1}^3T_i-2\sum\limits_{i=1}^nS_{n-i+1}^2T_{i}^2+\sum\limits_{i=1}^nS_{n-i+1}T_{i}^3\)。
注意到 \(f\leqslant n\times 67626\),虽然很大,但是直接猜测数据强度不高,直接开卷!
CF1107E Vasya and Binary String
设 \(f_{l,r}\) 为区间删完的贡献,然后错完了,因为会删除若干段然后剩下的合并起来。
那么考虑令 \(f_{l,r,x}\) 表示区间右边还有 \(x\) 个 \(s_r\),把区间和 \(x\) 个 \(s_r\) 全部删完的代价。
感觉很对,考虑转移:
- 清空 \(s_r\):\(f_{l,r,x}\gets f_{l,r-1,0}+a_{x+1}\)
- 加入 \(s_r\):枚举断点 \(k\) 且 \(s_k=s_r\),把 \([k+1,r-1]\) 删掉,\(f_{l,r,x}\gets f_{l,k,x+1}+f_{k+1,r-1,0}\)
发现可以覆盖到所有方案。
复杂度 \(O(n^4)\)。
P8352 [SDOI/SXOI2022] 小 N 的独立集
很明显的 dp of dp。
先考虑一种很有前途的原树 dp,令 \(f_{u,0/1}\) 表示子树 \(u\),点 \(u\) 是否选的代价。那么有 \(f_{u,1}-f_{u,0}\in[0,k]\),当 \(f_{u,1}<f_{u,0}\) 时限制显然更松,可以视为 \(f_{u,1}=f_{u,0}\)。
发现 dp 的意义其实就是 \(f_0\) 一定不选,\(f_1\) 不一定选。
对 \(f\) 直接 dp 计数即可,转移类似树上背包。
复杂度 \(O(n^2k^4)\),判 \(0\) 后跑得飞快。
任意模数多项式乘法
使用三模 NTT,理论答案不会超过 \(np^2<p_1p_2p_3\),最后暴力 crt 合并就好了。
可选 \(p=\{998244353,469762049,1004535809\}\),好处是拥有相同的原根 \(g=3\)。
常数巨大就是了。
喜欢我 \(9\) 倍常数么。
P10175 「OICon-02」Subtree Value
很幽默的题。
一个经典的树上连通块计数,外面枚举 \(|S|\) 里面做背包,估计是没法优化的。
但是注意到模数的特点 \(U^V\) 为底数很小,指数也很小。
注意到我们的瓶颈在于需要枚举 \(|S|\) 以确定它的值。
令 \(|S|=Ux+y\),那么在 \(\prod (Ux+(y+a_i))\) 中,根据分配率 \(Ux\) 只能乘进结果内不超过 \(V\) 次,不然取模就把他归零了。
那么我们状态记录算它了几次,就好了,最后再枚举 \(|S|\) 的值就做完了。
复杂度是神秘的 \(O(n^2UV^2)\)。
P9197 [JOI Open 2016] 摩天大楼
连续段 dp,是用来解决一类需要使用 dp 但是状态转移与临近值密切相关的计数问题。
首先,这道题需要将贡献进行一些转化。
考虑值域扫描线,从大往小扫,记录 \(a_i-a_{i-1}\) 被记录贡献多少次。
发现其实就是划分成了若干个段,贡献会发生在除了序列开头末尾的段头段尾。
那么可以令 \(f_{i,j,k,0/1,0/1}\) 表示现在扫到了 \(a_i\),现在有 \(j\) 个段,现在贡献为 \(k\),序列开头和结尾有没有钦定。
考虑转移,需要一些分类讨论:
- 这个数新开一个段,需要特判是否占了开头结尾。
- 这个数延续一个段,需要特判是否占了开头结尾。
- 这个数合并两个段,它一定不会出现在开头结尾。
复杂度 \(O(n^2L)\)。
调整法线性基
一个线性基的 trick,模拟赛碰到了,积累一下。
就是说,对于一个线性基,我们可以将其调整,调整为若 \(a_i\) 存在则其余 \(a_j,j\neq i\) 都有第 \(i\) 位为 \(0\)。
调整可以从高往低调整,是一个 \(O(\log^2n)\) 的复杂度。
使用这个调整后的线性基,可以证明出来一些有用的结论。
对于数 \(x\),其在线性基中能异或出的最大的数为 \(mx(x)\),最小的数为 \(mn(x)\)。
则 \(mx(x\oplus y)=mx(x)\oplus mn(y)\)。
有一个更平易近人的解释:我们要求 \(x\) 在线性基中异或出的最大的数 \(mx(x)\)。设 \(mn(x)=y\),则 \(mx(x)=mx(0)\oplus y\),其中 \(mx(0)\) 就是线性基能异或出的最大的数,调整后就是所有基的异或和。
正确性在于首先发现求 \(x\) 的答案和求 \(y\) 的答案是等价的,因为 \(x\) 到 \(y\) 只是异或上了一些线性基里面的数,那么对于 \(y\) 由于线性基是调整过的,有一个贪心是能放就放,这个能放在调整后可以视为 \(y\) 这一位为 \(0\)。由于是最小的,所以若 \(a_i\) 存在则 \(y\) 的第 \(i\) 位必定为 \(0\),就证完了。
这个有什么用呢?这个可以静态线性基拆位求区间线性基查询问题!
P4168 [Violet] 蒲公英
这个叫做 \(O(n\sqrt n)\) 求静态序列区间众数。
首先分块,预处理每个块的众数和每个块的前缀和的桶。
考虑一个询问,如果所处块同一个或者恰好相差 \(1\),那就暴力做。
否则,会拆成两个散段和一个整连续段块。
注意到众数只会存在于整段连续段块的众数和两个散段的数。
那么连续段块众数预处理了,直接拉出来,散段暴力做,就好了。
P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III
这题和蒲公英一样,但只需要输出次数,但是卡空间,怎么办呢?
当然可以不预处理那个桶,直接用 vector 存之后二分查找也可以,但这样是 \(O(n\sqrt{n\log n})\) 的。
考虑可以快速得到答案下界为中间的整段众数,设出现了 \(c\) 次,那么散段的数能篡位当且仅当出现了至少 \(x+1\) 次。
考虑枚举每一个散段中的数,如何判断是否出现了多余 \(x+1\) 次呢?
记录原数组每个数在 vector 中的下标,直接看看他右边 \(x+1\) 个是否在 \(r\) 以内就好了,如果更优就一直拓展。
发现这样做复杂度均摊正确,为 \(O(n\sqrt n)\)。
P8330 [ZJOI2022] 众数
来填三年前的坑。
首先考虑如果选了一段区间,那么答案集合就是区间外面的众数集合,次数就是外面众数次数加上里面众数次数。
有一个想法,一般众数类题目就难以 \(\text{polylog}\),所以可以考虑根号分治什么的。
设立阈值 \(B\),考虑出现次数 \(\geqslant B\) 的数,由于只有 \(\frac nB\) 个数,暴力枚举。
枚举到 \(x\) 时,再 \(O(n)\) 枚举另一个数 \(y\),然后分成 \(x\) 外 \(y\) 内和 \(x\) 内 \(y\) 外分别 \(O(cnt_y)\) 计算即可。
具体地,以 \(x\) 外 \(y\) 内为例,那么设一开始的贡献为 \(cnt_x\),对于区间里的 \(x\) 都有 \(-1\) 的贡献,\(y\) 都有 \(+1\) 的贡献,转化成最大子段和问题,可以在 \(x\) 处前缀和预处理做到 \(O(cnt_y)\)。
这一部分复杂度 \(O(\frac{n^2}B)\)。
那么现在只要考虑 \(x,y\leqslant B\) 的情况就可以了。
发现枚举数肯定不太行,尝试枚举区间。
首先让 \(a_{l-1}=x,a_{r+1}=x\) 一定不劣。
注意到选的区间的众数出现次数一定 \(\leqslant B\)。
预处理出 \(f_{l,i}\) 表示区间左端点为 \(l\) 区间众数次数为 \(i\) 的最小右端点。
外面枚举 \(x\),那么 \(l\) 的数量是 \(O(cnt_x)\) 的,然后可以直接通过 \(f\) 找到 \(r\)。
为了算 \(r\) 右边的数量可以二分,但这样多了一只 \(\log\),但是这可以扫描线双指针解决。
这部分复杂度 \(O(nB)\)。
取 \(B=\sqrt n\) 可以获得复杂度 \(O(n\sqrt n)\)。
CF1823F Random Walk
考虑先写出转移式。
令 \(f_u\) 表示期望次数。
则 \(f_t=1\),\(f_u=[u=s]+\sum\limits_{(u,v)\in E,v\neq t}\frac{f_v}{deg_v}\)。
可以使用一手经典的树上高消做到 \(O(n)\)。虽然其实是 \(O(n\log p)\)。
P5643 [PKUWC2018] 随机游走
首先相当于是求到达时间最大值的期望,先 min-max 成最小值。
那么就是要求出 \(f_{u,S}\) 表示从 \(u\) 出发走到点集 \(S\) 中任意一个点的期望步数。
首先对于询问 \(u,T\) 的答案就是 \(\sum\limits_{S\subseteq T,S\neq \varnothing}(-1)^{|S|+1}f_{u,S}\),预处理出 \(f\) 之后可以 \(O(q2^n)\) 做,当然这可以做一遍子集和后做到 \(O(n2^n)\) 预处理 \(O(1)\) 查询。
考虑求解 \(f\),先写出转移式。
则 \(u\in S,f_{u,S}=0\)。\(u\not\in S,f_{u,S}=1+\frac1{deg_u}\left(f_{fa_u,S}+\sum\limits_{v\in Son_u}f_{v,S}\right)\),然后变成经典的树上高消。
那么就做完了。

浙公网安备 33010602011771号