Loading

【杂题乱写】2024.01 #1

Page Views Count

Luogu-P5046 Ynoi2019 模拟赛 Yuno loves sqrt technology I

数据范围和时限指出本题复杂的几乎不可能带 \(\log\),考虑一个分块做法。

对于散块可以直接每个块内点对求出是否有逆序对,然后做二维前缀和。

不带 \(\log\) 的逆序对处理方法只能是预先排好序然后归并,这样瓶颈是没有 \(\log\) 的。所以可以对每个块先排好序,容易归并处理出第 \(i\) 个块与位置 \(j\) 的逆序对个数,做一个前缀和就行了。

还剩下两个散块的贡献,这部分直接拿出来再归并一次。

提交记录:Submission - Luogu

CodeForces-1392I Kevin and Grid *3300

这题课件上先给了平面图欧拉公式:\(|V|-|E|+|F|=2\),联通块个数公式:\(|C|=|V|-|E|+|F|-1\)

\(|V|\)\(|E|\) 都是非常好算的,大概是把两个桶函数卷积,\(|V|\) 就是直接卷,\(|E|\) 就是相邻两个都小于或大于等于才有贡献,取 \(\max\)\(\min\) 就行了。

考虑算 \(|F|\),发现题目中小于的权值减去大于等于的权值以及是否和边界相邻权值不同是很突兀的,除了外面无限延伸的面以外,如果某个连通块内还有其他连通块,那么对 \(|F|\) 而言增加了 \(1\),对被包含的连通块而言也增加了 \(1\),二者异色是减法关系,所以抵消了。唯一有用的 \(|F|\) 就是内部不含其他连通块的,也就是小正方形,这也是好算的。

NTT 需要用一个大模数或者双模数 CRT 合并。

考虑 \(|F|\) 的时候没把权值拿进来手模几个,感觉和正解擦肩而过了。

提交记录:Submission - CodeForces

Gym-102864 Prefix Sum

\(n,k\) 的数据范围看着比较有指向性,考虑根号重构。

求前缀和显然是卷一个 \(\frac{1}{(1-x)^k}\),展开是 \(\sum_{i\ge 0}\binom{k+i-1}{i}x^i\),过程就是平凡的牛顿二项式。

之后每 \(B\) 次修改重构一次,重构方法是 NTT,暴力处理的部分系数也是上面的组合数,区间询问就再做一次前缀和就行了。

还有一个牛客版本的,\(n\le 10^5,k\le 40\),模数 \(10^9+7\),把 NTT 改成暴力前缀和。

提交记录:Submission - Gym

CodeForces-1842G Tenzing and Random Operations *2800

必须要考虑一个和 \(m\) 无关的算法,注意到题目要求 \(\prod_{i=1}^n \left(a_i+\sum_{j=1}^m x_{j,i}\right)\) 的期望,其中 \(x_{j,i}\) 是表示第 \(j\) 次操作覆盖到 \(i\) 位置的随机变量,可以分配律展开成若干 \(n\)\(a\)\(x\) 的乘积之和。

分别考虑每个乘积,注意到对于同一个 \(j\),只需要考虑出现在这个乘积中的第一个 \(x_{j,i}\) 后面的如果 \(x_{j,i}\) 不为零则后面的一定贡献 \(v\),否则后面贡献什么也没有实际作用。

考虑 DP,设 \(f_{i,j}\) 表示考虑每个乘积的前 \(i\) 项,已经有 \(j\) 类随机变量加入到这个乘积当中,转移是讨论这次加入的元素:

\[f_{i,j}\leftarrow f_{i-1,j}\times a_i \]

\[f_{i,j}\leftarrow f_{i-1,j}\times j\times v \]

\[f_{i,j}\leftarrow f_{i-1,j-1}\times (m-j+1)\times \dfrac{i}{n}\times v \]

提交记录:Submission - CodeForces

AtCoder-ARC116_E Spread of Information

这种最优化问题考虑二分,最后是要求让每个节点都至少有一个关键点距离 \(\le mid\) 的最少关键点数。

考虑贪心,记 \(f_u\)\(u\) 子树内距离 \(u\) 最近的关键点距离,\(g_u\)\(u\) 子树内距离 \(u\) 最远的未被关键点覆盖的节点距离,转移之后如果 \(f_u+g_u\le mid\),那么就能通过 \(u\) 的某一子树的关键点覆盖其他子树未被覆盖的位置。如果不能覆盖且 \(g_u=mid\),那么必须在 \(u\) 设关键点。同时在根节点位置如果还有未被覆盖的节点也要再设一个关键点。

想到贪心之后后面确实没想到,一直在纠结如果状态里有数量,直接记录此时的最短距离是不是错的,和正解完全偏离了,这种最后一步差临门一脚的题目很难受,还是要多练。

提交记录:Submission - AtCoder

Luogu-P9754 CSP-S 2023 结构体

纯写。

提交记录:Submission - Luogu

CodeForces-150E Freezing with Style *3000

中位数的经典套路是二分答案,\(\ge mid\) 的数超过一半就行。

树上路径问题考虑点分治,固定一个分治中心,记 \(d_u\)\(u\) 到分治中心的距离,\(w_u\)\(u\) 到分治中心路径上 \(\ge mid\) 的边数。如果不考虑容斥的一些要求,需要的条件是 \(d_u+d_v\in [L,R]\)\(w_u+w_v\ge \left\lceil\frac{d_u+d_v}{2}\right\rceil\),后者等价于 \(2(w_u+w_v)\ge d_u+d_v\)

整理一下,记 \(f_u=2w_u-d_u\),有贡献的点对起码要满足 \(f_u+f_v\ge 0\),可以离线排序,数据结构以 \(d_u\) 为下标,每次加入一个信息,区间求一些东西。

现在还要考虑容斥掉多余的信息,注意到题目只要一个合法解,同时上面的维护离线方法使每个点对可以计算两次(枚举到两个节点时各一次),那么不妨对每个节点记录一下它属于哪个分治子树,线段树维护关于分治子树编号的最值,如果和当前枚举的节点不属于同一分治子树就有贡献。

时间复杂度 \(O(n\log^3 n)\),比较卡常。

提交记录:Submission - CodeForces

Luogu-P2371 国家集训队 墨墨的等式

同余最短路。

任取一个非零的 \(a_i\) 记作 \(A\),考虑对每个 \(j\) 求出 \(f_j\) 表示所有模 \(A\)\(j\) 的等价类中最小的一个能被表示出的数,那么判断一个数 \(k\) 能否被表示就只需要判断是 \(k\ge f_{k\bmod A}\)

由于 \(A\) 比较小,可以直接跑最短路,转移类似 \(dis_j+a_i\rightarrow dis_{(j+a_i)\bmod A}\)

查询区间 \([L,R]\) 就等价于查询两个前缀,一个前缀 \([0,R]\) 的答案是:

\[\sum_{j=0}^{A-1} \max\left(\left\lfloor\dfrac{R-f_j}{A}\right\rfloor+1,0\right) \]

提交记录:Submission - Luogu

Luogu-P4156 WC 2016 论战捆竹竿

相当于每次加上除去 \(\mathrm{border}\) 的部分,是同余最短路问题。

降低复杂度需要从 Border Series 入手,得到 \(O(\log n)\) 个三元组 \((a,d,l)\),表示可以增加长度为 \(a+id\) 的字符串,其中 \(i\in [0,l]\)

对每种等差数列依次考虑肯定是正确的,对三元组 \((a,d,l)\) 求模 \(a\) 的同余最短路,转移会形成 \(\gcd(a,d)\) 个环,可以对这些环分别考虑。其中转移前的最小值一定不会被转移,也不会有其他转移跨过这个最小值,可以从这个位置断开,之后转移只剩 \(l\) 的限制,可以单调队列优化。

之后考虑如何把模 \(a\) 的同余最短路转成模 \(a'\) 的同余最短路,不妨看做多源,初始值 \(f_i\rightarrow g_{f_i\bmod a'}\),同样也形成了 \(\gcd(a,a')\) 个环,选最小值断开,此时转移没有任何限制,直接前缀 \(\min\) 优化就行了。

提交记录:Submission - Luogu

Luogu-P4548 CTSC 2006 歌唱王国

\(f_i\) 表示在长度为 \(i\) 时完成的概率,\(g_i\) 表示在长度为 \(i\) 时尚未完成的概率,记 \(F(x),G(x)\)\(f,g\) 的生成函数,结合常数项 \(f_0=0,g_0=1\) 可以得到:

\[F(x)+G(x)=xG(x)+1 \]

考虑将一个未完成的串后面直接接上目标串,此时可能出现没有完全接完就已经完成了的情况(原来就有一部分前缀),已经接上的部分既是前缀也是后缀,即 \(\mathrm{border}\),剩下的部分就浪费了,所以可以写成:

\[\dfrac{x^LG(x)}{m^{|s|}}=\sum_{i=1}^{|s|} \dfrac{x^{|s|-i}F(x)}{m^{|s|-i}}[s[1,i]\in\mathrm{Border}(s)] \]

因为要求 \(F'(1)\),所以对第一个式子求导,得到:

\[F'(x)+G'(x)=G(x)+G'(x) \]

所以 \(F'(1)=G(1)\),再把 \(x=1\) 代入第二个式子。

\[G(1)=\sum_{i=1}^{|s|}m^i[s[1,i]\in\mathrm{Border}(s)] \]

所以答案就是 \(m\) 的所有 \(\mathrm{border}\) 次幂之和。

提交记录:Submission - Luogu

HDU-6791 Tokitsukaze, CSL and Palindrome Game

算期望是套上面的东西,所以就是把所有 \(\mathrm{border}\) 拿出来从大到小排序比字典序。

注意到回文串的一个好性质:\(\mathrm{border}\) 也是回文串。所以拿 PAM 出来在 \(\mathrm{fail}\) 树上定位端点然后倍增就行了,比较用哈希。

但是伟大的 HDU 会 TLE!!!

AtCoder-ARC112_F Die Siedler

首先一个人类智慧转化:将序列 \(a\) 对应到 \(A=\sum_{i=1}^n a_i\prod_{j=1}^{i-1} 2j \bmod M\) 其中 \(M=\prod_{i=1}^n 2i-1\)。容易发现进行换牌的操作时,\(2i\) 张第 \(i\) 种牌变成 \(1\) 张第 \(i+1\) 种牌,对 \(A\) 的结果没有影响,而 \(2n\) 张第 \(n\) 种牌换成 \(1\) 张第 \(1\) 种牌也恰好模 \(M\) 同余。这类似变进制数,对任意的 \(A\) 都能找出 \(\sum a_i\) 最小的序列 \(a\),方法是从高到低进制转换。

考虑加牌的操作也能转化成 \(m\)\(B_i\),根据裴蜀定理,设 \(G=\gcd(\gcd_{i=1}^m \{B_i\},M)\),那么可以得到任意的 \((A+kG)\bmod M\)

如果 \(G\) 比较大,可以得到一个 \(O\left(n\dfrac{M}{G}\right)\) 的做法,即暴力枚举 \(k\)

现在要找一个 \(G\) 比较小的做法,由于 \(G\mid M\),可以直接看作跑同余最短路,找到与 \(A\)\(G\) 同余的所有数中需要的各位之和的最小值,复杂度 \(O(nG)\)

注意到当 \(A+kG\equiv 0\pmod M\) 时的方案是不合法的,这里要特殊判断一下。

实际 \(G\) 不足 \(\sqrt{M}\) 级别,\(M\) 最大的小于根号的因子是 \(1214827\)

提交记录:Submission - AtCoder

CodeForces-1242D2 Beautiful Bracket Sequence (hard version) *2900

考虑一个已知的括号序列怎么求删去一些得到合法序列的深度,发现直接删成若干左括号和若干右括号就行,那么一个位置的贡献就是左侧的左括号和右侧的右括号个数的较小值,容易发现一定存在一个位置使二者相等,此时取到最大值。

一个形式化的观察是记 \(f_i\)\([1,i]\) 中左括号个数减去 \([i+1,n]\) 中右括号个数,发现 \(i\) 向右移动一位 \(f_i\) 必然增加 \(1\),于是 \(f_i-i\) 是定值,因此仅存在唯一的位置取到 \(f_i=0\)

枚举当前的位置,设左侧有 \(l\) 个左括号和 \(x\) 个未知的位置,右侧有 \(r\) 个右括号和 \(y\) 个未知的位置,那么枚举左侧有多少选了左括号,就对应得到右侧有多少选右括号:

\[\begin{aligned} &\sum_{i=0}^x(l+i)\dbinom{x}{i}\dbinom{y}{l+i-r}\\ =&l\sum_{i=0}^x\dbinom{x}{i}\dbinom{y}{l+i-r}+x\sum_{i=0}^{x-1}\dbinom{x-1}{i}\dbinom{y}{l+i+1-r}\\ =&l\sum_{i=0}^x\dbinom{x}{i}\dbinom{y}{y+r-l-i}+x\sum_{i=0}^{x-1}\dbinom{x-1}{i}\dbinom{y}{y+r-l-i-1}\\ =&l\dbinom{x+y}{y+r-l}+x\dbinom{x+y-1}{y+r-l-1} \end{aligned}\]

这样每个位置可以 \(O(1)\) 计算。

提交记录:Submission - CodeForces

AtCoder-HITACHI2020_F Preserve Diameter

分析性质找充要条件然后数数,很厉害的题目。

以图的直径端点为根,找出图的一棵 BFS 树,应当满足以下性质:

  • 树上深度差不超过 \(1\) 的点对之间一定都有连边,否则增加这条边不会改变直径大小,不符合题意。

  • 树上深度差超过 \(1\) 的点对之间一定没有连边,否则不符合 BFS 树的要求。

  • 树上直径应当是唯一的,否则可以存在方法改变其中一条直径但不改变另一条,使得直径数量减少而长度不变。

直径的问题可以从中点出发 DP,把所有给出的树上的边赋 \(-1,0,1\) 的权值,表示父亲与儿子在 BFS 树上深度的差,那么要求恰好有权值为正负直径一半的根链各一条,注意每条直径会被定向两次。

直径中点是一条边的情况就分成两棵树 DP,合并直接钦定一条边的方向。

提交记录:Submission - AtCoder

CodeForces-1450H2 Multithreading (Hard Version) *3300

还是先对一种已知的情况求答案,记 \(k\) 为奇数位置上黑点个数与偶数位置上黑点个数之差,\(m\) 为未知位置的个数,那么答案是 \(\frac{|k|}{2}\)

先证明答案上界是 \(\frac{|k|}{2}\),取相邻两个黑色点连边(相邻指中间只有白色点或没有点),如果这两个点奇偶性不同,中间的白色点内部就能匹配完,所以也不会产生新的交点,那么最坏的情况就是删去了所有这样的点对后剩下黑白相间的 \(2k\) 个点,其中每 \(4\) 个形成两条边一个交点,所以上界是 \(\frac{|k|}{2}\)

然后证明答案的下界是 \(\frac{|k|}{2}\),先将一个方案调整,使得匹配都是连接相邻两个同色点,此时至少有 \(\frac{|k|}{2}\) 个黑色边端点奇偶性相同,中间的一个白点就会连出去产生交点。

之后考虑一些未知的位置,可以钦定所有的奇数位置的都是黑点,那么每个未知的位置都等概率的使 \(k\) 减少 \(1\) 或不变,所以答案是:

\[\dfrac{1}{2^{m-1}}\sum_{i=0}^m \frac{|k-i|}{2}\dbinom{m}{i}[i\equiv k\pmod 2] \]

把常数提出来,拆绝对值,发现要算的是:

\[k\sum_{i=0}^k\dbinom{m}{i}[i\equiv k\pmod 2]-m\sum_{i=0}^{k-1}\dbinom{m-1}{i}[i\equiv k-1\pmod 2] \]

以及

\[m\sum_{i=k}^{m-1}\dbinom{m-1}{i}[i\equiv k-1\pmod 2]-k\sum_{i=k+1}^m\dbinom{m}{i}[i\equiv k\pmod 2] \]

第一个和第四个求和号类似,第二个和第三个求和号类似,合并起来,对于第一个和第四个,可以运用帕斯卡公式展开一次:

\[k\left[\sum_{i=0}^k\dbinom{m-1}{i}-\sum_{i=k+1}^{m-1}\dbinom{m-1}{i}\right]=k\left[2\sum_{i=0}^k\dbinom{m-1}{i}-2^{m-1}\right] \]

发现每两个产生贡献正好填满了所有位置,剩下超出的下指标要么小于零要么大于上指标,形式是很整齐的。

组合数前缀和移动一维 \(O(1)\) 计算非常经典,实际也可以根据第一个和第四个求和号的组合数前缀和推出第二个和第三个的。要注意 \(m=1\) 的情况,此时第二个和第三个求和号求出的东西因为上指标是负数并不好算,但整个式子的结果是可以 \(O(1)\) 计算的,特判即可。

提交记录:Submission - CodeForces

posted @ 2024-01-04 10:16  SoyTony  阅读(76)  评论(0编辑  收藏  举报