2024.1 杂题
To be a rock and not to roll.
这篇文章,以及以后可能的一些文章,会把同一个来源的题丢一块。
- 牛客挑战赛 72 C. Crying 与哈密顿路
- D. Crying 与 404
- E. Crying 与初中数学
- 牛客挑战赛 71 D. 权值和 plus
- E. 寻找中位数 plus
- QOJ4824 Bracket-and-bar Sequences
- QOJ4826 Find the Parts
- QOJ2566 Inversions
- 「JOISC 2020 Day4」Capital City
- LOJ6485 LJJ 学二项式定理
- LOJ6499 颜色
- LOJ6077 逆序对
- 洛谷 P5591 小猪佩奇学数学
- CF1558F Strange Sort
- CF1556G Gates to Another World
- CF1093G Multidimensional Queries
- CF207C Game with Two Trees
- CF600F Edge Coloring of Bipartite Graph
- ARC161E Not Dyed by Majority (Cubic Graph)
- ARC160F Count Sorted Arrays
- ARC151E Keep Being Substring
- AGC027E ABBreviate
- 「BJOI2016」水晶
- 「SDOI2017」序列计数
牛客挑战赛 72 C. Crying 与哈密顿路
Tag:D-树形 DP;D-背包。
令 \(f_{u,i}\) 表示 \(u\) 子树内的节点连出 \(i\) 条子哈密尔顿路的最优解,转移类似树形背包。
即 \(f_{u,i}+f_{v,j}+ka_u\to f'_{u,i+j-k}\),其中对于 \(k\) 的枚举有上界 \(2\min(i,j)\),对应将对应的若干条哈密尔顿路首尾相接。
总复杂度 \(O(n^3)\),Code。
D. Crying 与 404
Tag:S-主席树。
因为是排列,所以 \([l,r]\) 内没有的数,就是 \([1,l-1]\cup [r+1,n]\) 里有的数。
使用主席树求第 \(k\) 大即可,注意要特判 \(k\ge r-l+1\) 的情况,\(O(n\log n)\),Code。
E. Crying 与初中数学
Tag:M-整除分块;M-莫比乌斯反演;M-杜教筛;M-线性筛。
尝试枚举 \(a,b\),即求:
可以结合 \(\mu\) 的定义得到上述式子,套路展开成:
首先对于所有的 \(a\),\(N/a^2\) 的个数是有限的,大致是 \(O(N^{1/3})\) 量级。
有经典结论:
可导出:
对外层按 \(N/a^2\) 分段,内层则同样是类似的分段方式,剩下的就是求 \(\sum \mu(i)\) 和 \(\sum \mu(i)i^2\),两者均可以用杜教筛带走。
需要设置合理的预处理范围,出题人题解说复杂度是 \(O(N^{3/7})\) 的,但是我不会证,Code。
感觉这类的数论题大部分都需要整预处理来平衡复杂度,很厉害。
牛客挑战赛 71 D. 权值和 plus
Tag:M-原根;M-模意义下对数;M-多项式快速幂。
首先对 \(S_i\) 取 \(\log\),这样可以使得问题变成 \(\sum\)。
第 \(i\) 个数和任意一个数并没有区别,只需要求出某个数出现的次数即可,即模意义下背包 \(K-1\) 个数背出某个数的方案,剩下的一个数可以一一对应。
\(K\le 10^5\),故转成生成函数施多项式快速幂即可,不过这里因为是模意义下的可能只能朴素 \(O(P\log P\log K)\) 的来做,最后统计答案是简单的,感觉有点刻意,Code。
E. 寻找中位数 plus
Tag:S-线段树。
令 \(>k\) 的数为 \(+1\),\(<k\) 的数为 \(-1\),\(k\) 为 \(0\),则中位数为 \(k\) 就意味着这个区间至少有一个 \(0\),且区间的总和为 \(0\) 或 \(1\)。
但是目前还是不好找区间,但是有结论:如果存在合法区间,则一定存在一个区间,满足他的左端点或右端点为 \(0\),证明略。
于是使用线段树维护第一个 \(0\) 向右的总和,最后一个 \(0\) 向左的总和,当前区间前缀的最大值,当前区间后缀的最大值,即可合并答案,\(O(n\log n)\),Code。
QOJ4824 Bracket-and-bar Sequences
Tag:D-计数 DP。
写个暴力会发现合法的括号序列个数比 \(2\times 10^{18}\) 要小,所以直接按照一定顺序编号即可,有点细节但不多。
然后写暴力试填即可,Code。
QOJ4826 Find the Parts
Tag:H-构造;H-哈希;cin 的使用方法。
发现我们可以用的 bit 数量大约是矩阵的 \(\frac{1}{10}\),直接对着这个想。
发现存下来第 \(10n\) 行就行了,这样一定可以存下来查询矩阵的某一些东西,然后就可以跑哈希直接找到这个矩阵里面的某一行了。
复杂度没算,但是好像有点慢,不管了能过,Code。
QOJ2566 Inversions
Tag:M-生成函数;M-多项式 exp;M-多项式 ln;H-分段打表;M-自然数幂和。
令 \(F(x)\) 表示对应的生成函数,则有 \(F(x)=\frac{\prod_{i=1}^n(1-x^i)}{(1-x)^n}\),令 \(F(x)=\sum f_ix^i\),有结论:
证明:对于任意生成函数 \(G(x)\),令 \(g_i\) 为 \(G(x)\) 的第 \(i\) 项系数,有:
得证,则需求:
令 \(G(x)=\ln\frac{1-e^x}{x}\),\(g_i\) 为 \(g_x\) 的系数,则有:
使用斯特林数求出自然数幂和,分块打表求 \(n!\),则整个问题可以在 \(O(k^2)\) 内解决,这里只需要写 \(O(k^2)\) 多项式操作,也可以做到 \(O(k\log k)\) 但没必要,Code。
「JOISC 2020 Day4」Capital City
Tag:H-贪心;T-点分治。
有贪心:任取某个点为根,现在试图将这个根到与其同颜色的点打通,则枚举每一个同颜色的点向上跳父亲直到跳到同颜色即可,注意可能中途会加入其它节点。
有性质:如果在某一方案中染色到了 \(x\),则从 \(x\) 出发的染色方案一定不劣于当前的方案,证明:显然有上界次数为直接把这个方案拿过来用。
使用点分治来加速贪心的过程,每次贪心的时候发现贪心的部分越出了子树就跳出不做,即可做到 \(O(n\log n)\),Code。
LOJ6485 LJJ 学二项式定理
Tag:M-单位根反演。
单位根反演即:\([n|a]=\frac{1}{n}\sum_{k=0}^{n-1}\omega_n^{ak}\)。
可以导出 \([a\bmod p=b]=[p|(a-b)]=\frac{1}{p}\sum_{i=0}^{n-1}\omega_n^{ai}\omega_n^{-bi}\) 这样的式子。
对于原题,施单位根反演得:
在 \(\bmod 998244353\) 意义下计算 \(\omega_4\) 是简单的,Code。
LOJ6499 颜色
Tag:S-分块;S-ST 表;S-四毛子。
听说这个东西就叫四毛子?
注意到问题很强,考虑分块乱搞,令块长为 \(B\),使用 bitset 维护每一块的信息,块间使用 ST 表来维护,这样预处理复杂度 \(O(\frac{n^2}{B\omega}\log \frac n B)\),单次询问复杂度 \(O(B+\frac{n}{\omega})\),取 \(B=\frac{n}{\omega}\),即可做到 \(O(n\log \omega+\frac{nm}{\omega})\) 的优秀复杂度,可能有更优块长,Code。
LOJ6077 逆序对
Tag:M-生成函数;D-背包 DP。
对于长度为 \(n\) 的序列,考虑将每个数依次插入序列中,则可以得到生成函数 \((1+x)(1+x+x^2)\ldots(1+x+\ldots +x^{n-1})\),同除 \((1-x)\) 得到 \(F(x)=\frac{\prod_{i=1}^n (1-x^i)}{(1-x)^n}\)。
接下来只需要求出 \([x^k]F(x)\) 了,首先有 \(\frac{1}{(1-x)^n}=\sum_{i\ge 0} \binom{n+i-1}{n-1} x^i\),可以联系插板法证明,分子则可以看成取出若干个数其和为 \(s\),取出奇数个数则贡献为 \(-1\),否则贡献为 \(1\)。
令 \(f_{i,j}\) 表示取 \(i\) 个数总和为 \(j\) 的方案数,因为有 \(k\) 的限制,所以 \(i\le \sqrt{k}\),状态数正确,考虑转移即可。
- 令当前背包内的所有值 \(+1\),\(f_{i,j}\to f_{i,j+i}\);
- 令当前背包内的所有值 \(+1\),并塞个 \(1\) 进来:\(f_{i,j}\to f_{i+1,j+i}\);
- 除去加入 \(n+1\) 的情况:\(-f_{i,j}\to f_{i+1,j+n+1}\)。
转移后卷积即可,时间复杂度 \(O(k\sqrt{k})\),Code。
洛谷 P5591 小猪佩奇学数学
Tag:M-单位根反演。
可以将 \(\lfloor\frac i k\rfloor\) 拆成 \(\frac 1 k (i-(i\bmod k))\),则有:
先只看左侧,可以将 \(i\) 置换进组合数,可以得到:
可以 \(O(\log n)\) 的解决,考虑右边,枚举 \(i\bmod k\) 有:
目前已经导出了一个 \(O(k^2)\) 做法,但是 \(\sum_{j=0}^{k-1}j\omega_k^{-jl}\) 这个形式是错位相减,可以导出 \(O(\log k)\) 的计算式。
下面写一下推导:令 \(S(n,k)\) 表示 \(\sum_{i=0}^{n-1} ik^i\),有结论,此时的 \(S(n,k)=(An+B)k^n-B\),其中 \(A,B\) 为参数。
注意到此时 \(k^n=(\omega_k^{-l})^k=1\),所以 \(S(n,k)=An\),结合结论有 \(A=\frac{1}{k-1}\),即 \(S(n,k)=\frac{n}{k-1}\),注意要特判 \(k=1\)。
做到 \(O(k\log k)\),done,Code。
CF1558F Strange Sort
Tag:S-线段树。
感觉同上啊,先转成 \(01\) 序列,发现我们的答案就是对于所有 \(x\) 求一下最大值,然后注意到扫描 \(x\) 的过程相当于单点 \(1\to 0\),这很好,尝试讨论一下 \(01\) 序列的答案。
令 \(f_i\) 表示第 \(i\) 个 \(0\) 移到他的对应位置需要多少轮,分情况讨论:
- 移动的过程中,前一个 \(0\) 挡住了当前的 \(0\),轮数就会是 \(f_{i-1}+1\);
- 全程没人挡着,那就是前面的 \(1\) 的个数加上当前位置的奇偶性。
目标为 \(f_m\),将式子拆开则有 \(f_m=\max(k_j+(p_j\bmod 2)+m-j)\),其中 \(k_j\) 是第 \(j\) 个 \(0\) 前面的 \(1\) 的数量,\(p_j\) 是第 \(j\) 个 \(0\) 的位置,枚举 \(m\) 使用线段树维护即可,可以看成维护左边 \(1\) 加上右边 \(0\) 再加上奇偶性,\(O(n\log n)\),Code。
CF1556G Gates to Another World
Tag:S-线段树;S-并查集。
操作以区间的形式表示,于是尝试建立动态开点线段树(很困难),发现题目的建边可以看成:对于每个点向左右两侧递归,并将对应的点连边。
时间倒流将删边变成加边,于是对于每个节点维护其对应被加入的时间,对于一个区间内相同加边删边的点,使用这个点对其整体维护,于是复杂度就对了。
\(O(n^2m)\),Code。
CF1093G Multidimensional Queries
Tag:S-线段树。
trick 罢了。
令 \(S\) 为 \(k\) 位二进制数,每一位表示正负性,则可以认为 \(a,b\) 的曼哈顿距离就是 \(\max_S(a(S)+b(MS\oplus S))\)。
分开维护 \(a(S)\) 和 \(b(MS\oplus S)\) 的最大值,使用线段树维护区间合并,即可在 \(O(2^kn\log n)\) 内维护出答案,Code。
CF207C Game with Two Trees
Tag:R-Trie;S-树状数组;S-树链剖分;H-倍增;R-字符串哈希
仅讲述 C3 做法。
令 \(q\) 为 \(j\) 的 \(l\) 级祖先,\(S(x,y)\) 表示 \(x\) 到 \(y\) 的路径所形成的字符串,则要求 \(S(i,1)=S(q,j)\)。
转成 \(S(1,i)=S(j,q)\),这个时候 \(T_1\) 就可以合并成一棵有点权的 Trie 树。
对于每一个 \(j\),考虑求出他能够匹配出的最长长度,其对应的节点 \(i\) 的祖先链都一定会有 \(1\) 的贡献。
考虑回过头来处理操作,考虑如下的维护方法:
- 加入 \(T_1\) 的节点时,查询当前节点的权值 \(b\),并给当前节点子树内的所有点权值 \(a\) 加 \(1\)。
- 加入 \(T_2\) 的节点时,对其对应的节点 \(i\),查询权值 \(a\),并给对应节点子树内的所有点权值 \(b\) 加 \(1\)。
容易拍平到 DFS 序上使用两个树状数组维护,现在只需要求出对应的节点 \(i\)。
枚举 \(j\),对 \(j\) 倍增跳,对 \(i\) 则将 \(T_1\) 重链剖分,每次沿重链倍增向下跳,跳到最底下走轻边,比较的过程使用哈希,于是倍增 \(\log n\) 次,就是 \(O(n\log^2n)\) 的了,Code。
不要拘泥于在线维护这样的事情,要考虑整体的处理以及问题的转化。
CF600F Edge Coloring of Bipartite Graph
Tag:G-二分图边染色。
答案为最大点度,构造方法是每次枚举一条边,然后求两边点集的最小可能颜色,如果颜色不相同就交叉染色即可。
时间复杂度 \(O(nm)\),Code。
ARC161E Not Dyed by Majority (Cubic Graph)
Tag:H-随机化;G-2-SAT。
啊?
结论:答案占比比较大。
随机答案,现在问题转化为写 checker,发现这东西就是一个 2-SAT,限制形如 \(a\) 取了 B
则 \(b,c\) 取 W
,这样的,直接建图即可。
Code。
ARC160F Count Sorted Arrays
Tag:D-计数 DP。
其实还算套路?使用不知道从哪里听来的套路:枚举 \(x\),将 \(\ge x\) 的数设为 \(1\),\(<x\) 的数设为 \(0\),则一个排列可以被拆成 \(n+1\) 个长度为 \(n\) 的 \(01\) 数组,认为排列有序当且仅当这些 \(01\) 数组均变得有序。
对所有的 \(01\) 数组模拟其排序的过程,则可以记录下来某个 \(01\) 数组最终被排成了谁,利用这个东西可以 DP 求出对应的原排列数,单次复杂度是 \(O(n2^n)\) 的,不能通过。
然而注意到其实有很多次操作都是无效操作,毛估估一下会发现有效操作的量级是 \(O(n^2)\) 的,每次暴力维护一下哪些操作是有效的就可以优化到 \(O(n^32^n)\),Code。
ARC151E Keep Being Substring
Tag:G-最短路;S-最长公共子串。
Type 1:存在公共子串
此时将 \(X\) 删到 \(LCS(X,Y)\),再扩充到 \(Y\) 最优,答案为 \(P+Q-2|LCS(X,Y)|\),可以使用你喜欢的方法做到 \(O(N)\),\(O(N\log N)\),\(O(N\log ^2N)\) 不等。
Type 2:不存在公共子串
发现此时只可能先将 \(X\) 删到只剩某一个字符,再从这一个字符出发走到另一个字符,扩展得到 \(Y\)。
建立图论模型,建立超级源点 \(S\),超级汇点 \(T\),建立如下边:
- \((S,X_i,0)\);
- \((Y_i,T,0)\);
- \((A_i,A_{i+1},1),(A_{i+1},A_i,1)\)。
设得到的最短路长度为 \(d\),则答案为 \((P-1)+(Q-1)+2d\),跑 \(01\) BFS 即可,复杂度 \(O(N)\)。
综上,可以在 \(O(N)\) 的时间复杂度解决该问题,偷懒写了 \(O(N\log^2N)\),Code。
AGC027E ABBreviate
Tag:D-计数 DP。
令 a
为 \(1\),b
为 \(2\),则在 \(\bmod 3\) 意义下整个序列的和不变。
考虑得到的字符串 \(t\),尝试把 \(s\) 划分成若干段,每一段均对应 \(t\) 每一位,可以证明若最后剩下的一段总和为 \(0\),则一定可以匹配出来。
考虑分段 DP,尝试划分每一段的最终答案,转移一定是从上一个前缀和不为 \(p_i\) 的位置转移过来,这样 DP 就可以了。
\(O(n)\),Code,好像很胡,但是算了。
「BJOI2016」水晶
Tag:G-网络流。
以 \(a_i+b_i+c_i\) 对 \(3\) 的余数分类,会发现不能够出现的连在一起的水晶满足 \(2,0,1\) 这样的模式。
套路的,建立最小割模型,对于 \(2,1\) 类型的点只需要分别连到超级源超级汇,对于 \(0\) 类型的点拆点,然后将不能够出现的水晶求一下就可以了,Code。
「SDOI2017」序列计数
Tag:D-计数 DP;M-矩阵快速幂。
没有第二条限制只需要令 \(f_{i,j}\) 表示 \(i\) 个数总和为 \(j\) 的总方案数,可以矩阵快速幂加速,\(O(p^3 \log n)\)。
有的话只需要容斥掉只选合数的情况,这可以再跑一遍矩阵快速幂,没了,Code。