杂题20210415
CF1220D Alex and Julian
给定正整数集合 \(B\) ,将所有 \(x\in\mathbf{Z}\) 看作图中一个顶点,若 \(i,\ j\in\mathbf{Z}\ (i\neq j)\) 满足 \(|i-j|\in B\) ,则在它们之间连一条无向边。问至少需要删掉多少个 \(B\) 中的元素,才能使得建成的图是一张二分图,找到一组方案
\(|B|\leq2\times10^5\) , \(B\) 中元素不超过 \(10^{18}\)
注意到如果 \(B\) 中元素均为奇数,建成的图必然是一张二分图
进一步地,若 \(B\) 中元素形如 \(a\times2^k\) ,其中 \(k\) 是常数, \(a\) 是奇数,建成的图也是一张二分图
而如果 \(B\) 中存在元素 \(a_1\times2^{k_1},\ a_2\times^{k_2}\ (k_1\neq k_2)\) ,必然会形成奇环
因此我们将所有元素按其包含的最高 \(2\) 的幂次分类,保留元素最多那一类即可
LOJ6030 「雅礼集训 2017 Day1」矩阵
有一个 \(n\times n\) 的矩阵,每个位置 \((i,\ j)\) 如果是
.
表示为白色,如果是#
表示为黑色。初始时,每个位置可以是黑色或白色的, \((i,\ j)\) 位置的值会作为 \(a_{i,\ j}\) 给你。
现在有一种操作,选择两个整数 \(i,\ j\in[1,\ n]\) ,记 \((i,\ 1),\ (i,\ 2),\ \cdots,\ (i,\ n)\) 的颜色为 \(C_1,\ C_2,\ \cdots,\ C_n\) ,将 \((1,\ j),\ (2,\ j),\ \cdots,\ (n,\ j)\) 的颜色赋为 \(C_1,\ C_2,\ \cdots,\ C_n\) 。
你的任务是将整个矩阵变成全黑,如果能够办到,输出最少步数,否则输出
-1
。\(n\leq1000\)
如果矩阵中至少有一个黑色格子,可以用它构造出一个黑色行,再用这个黑色行覆盖整个矩形即可
因此无解当且仅当矩阵全白
如果某一列不是全黑,那么我们一定会用全黑的一行去覆盖它,考虑枚举先把哪一行塞成全黑
假设枚举到第 \(i\) 行,如果不存在整数 \(j\in[1,\ n]\) 满足 \(a_{j,\ i}=\) #
,需要额外的一步,即需要构造出一个 \(a_{k,\ i}=\) #
,随便选一个非全零行即可
大概就是个贪心
LOJ6048 「雅礼集训 2017 Day10」数列
小 A 有 \(n\) 个正整数 \(A_1,\ A_2,\ \cdots,\ A_n\),紧接着,他打算依次在黑板上写下这 \(n\) 个数。对于每一个数,他可以决定将这个数写在当前数列的最左边或最右边。现在他想知道,他写下的数列的可能的最长严格上升子序列(可由不连续的元素组成)的长度是多少,同时他还想知道有多少种不同的最长的严格上升子序列。
两个子序列被认为是不同的,当且仅当:两个子序列属于两个不同的写序列的方案(两个写序列中有至少一步是不一样的)或两个子序列位于同一写序列方案的不同位置。
由于结果可能很大,所以小 A 只需要知道最长严格上升子序列的方案数对 \(10^9+7\) 取模的结果。
\(n\leq2\times10^5\)
考虑某个写下来的数列的 LIS,假设其对应原序列下标 \(i_1,\ i_2,\ \cdots,\ i_k\) ,那么有 \(i_1>i_2>\cdots>i_p<i_{p+1}<\cdots<i_k\)
因此我们记 \(A'=R(A)+A\) ,即将原序列的反转和原序列顺序连接起来,那么 \(A'\) 的 LIS 的长度就等于原题答案
接下来我们给 \(A'\) 右半部分所有元素减去 \(0.5\) 以避免一些特殊情况(实际上没有必要
而不在 LIS 中的元素可以选择放在左侧或右侧,有 \(2\) 的贡献。因此答案即为 \(A'\) 的 LIS 方案数乘以 \(2^{n-|LIS|}\)
注意要特判 \(|LIS|=n\) 的情况的方案数
CF1498E Two Houses
有一个 \(n\) 个点的竞赛图,你不知道它的形态,但你知道每个点的入度 \(k_i\)
你每次可以向交互器询问一对整数 \((x,\ y)\ (x\ne y)\) ,交互器会返回从 \(x\) 出发是否能到达 \(y\) ,如果交互器有一次返回了真,那么你就不能再询问了。你不能询问同一有序点对,交互次数没有上限
你需要找到 \(|k_x-k_y|\) 最大的一对点之一
\(n\leq500\)
将竞赛图缩成若干个强连通分量,我们称之为大点,那么我们要找一对点满足它们处于同一大点且 \(|k_x-k_y|\) 最大
将所有大点按拓扑序升序依次写下来,即靠前的大点中的点会向靠后的大点中的点连边
假设我们要向交互器询问 \((x,\ y)\) ,且 \(x\) 所属的大点在 \(y\) 所属的大点之后,考虑 \(x\) 的入度构成,为部分 \(x\) 所属大点中的点和 \(x\) 所属大点之前的大点中的所有点, \(y\) 的入度构成同理,因此 \(x\) 的入度必然大于 \(y\) 的入度,而此时 \(x\) 必然不能到达 \(y\)
因此我们将所有点对按照 \(|k_x-k_y|\) 降序枚举,每次询问从 \(k_i\) 较大的点出发是否能够到达 \(k_i\) 较小的点,第一次返回真的点对即为答案
但存在一种不需要询问的线性优秀做法
先将所有点按入度升序排序,将每一个满足 前 \(i\) 个点入度和等于 \(\frac{i(i-1)}2\) 的前缀 \(i\) 标记,对于两个相邻的标记点 \(i,\ j\) ,区间 \([i+1,\ j]\) 中的点构成了一个极大强连通分量,证明比较显然
CF757G Can Bash Save the Day?
给定一棵 \(n\) 个点的树,和一个 \(n\) 的排列,有 \(q\) 次询问:
1 l r x
,询问 \(\displaystyle\sum_{i=l}^r\text{dis}(p_i,\ x)\)2 i
,交换 \(p_i\) 与 \(p_{i+1}\)\(n,\ q\leq2\times10^5\)
建出边分树,一种 naive 的想法是对每一层建一棵维护 \(p_i\) 到这一层的边分中心距离的某种数据结构,修改时对每一层的数据结构修改,时间复杂度 \(O((n+q)\log^2n)\) ,比较难受
一种更为优秀的做法是,考虑在边分树上询问的过程,每次会从当前点走到其左右儿子之一,并将另一个儿子中的所有 \(i\in [l,\ r]\) 的 \(p_i\) 加入贡献,而这在 dfs 序上是连续的一段。因此考虑将 \(p_i=1,\ 2,\ \cdots,\ n\) 的点的 dfs 序,依次加入边分树中,并可持久化。一次修改只会影响 \(i\) 和 \(i+1\) 这两个版本的主席树
时空复杂度 \(O((n+q)\log n)\)
Luogu5972 [PA2019]Desant
给定排列 \(a_1,\ a_2,\ \cdots,\ a_n\) ,对于每个 \(k\) ,求出 \(a_i\) 的长为 \(k\) 的子序列中的逆序对数量最小值,与达到这个值的子序列数量
\(n\leq40\)
\(O(2^nn)\) 枚举是显然的,但不太好优化
对于最暴力的状压 dp,即 \(f_{i,\ S}\) 表示对于前 \(i\) 个元素,选的权值集合为 \(S\) ,所得的逆序对数量最小值
注意到我们只关心集合 \(S\) 中的元素与整个序列后 \(n-i\) 个元素的大小关系,不妨考虑 \(a_{i+1},\ a_{i+2},\ \cdots,\ a_n\) ,将它们升序排序得到序列 \(b_1,\ b_2,\ \cdots,\ b_{n-i}\) (假设 \(b_{n-i+1}=n+1\) ),那么我们的状态可以记录对于 \(1\leq j\leq n-i\) ,区间 \([b_j,\ b_{j+1})\) 包含 \(S\) 中的元素个数
可以仍然用一个二进制数 \(T\) 表示状态 ,将区间 \([b_j,\ b_{j+1})\) 的值全部往左靠齐(即假设该区间内有 \(x\) 个元素,那么我们将 \(T\) 的 \(b_j\) 至 \(b_j+x-1\) 位填为 \(1\) )
写完之后会发现它跑得飞快!!1
考虑理性分析状态数,相当于是求 \(\displaystyle\max_{1=b_0<b_1<\cdots<b_k=n}{\prod_{j=1}^k(b_j-b_{j-1})}\) ,可以发现用 \(b_1,\ b_2,\ \cdots,\ b_{k-1}\) 等分 \([1,\ n]\) 是最优的。记 \(x\) 为将 \([1,\ n]\) 划分为了多少份,即求 \(f(x)=(n/x)^x\) 的最大值,求一下导可以发现 \(x\) 在取到 \(n/e\) 的时候 \(f(x)\) 取得最大值,而由于 \(b_j\) 都是实数,故区间长度为 \(3\) 的时候能让状态数取到最值,大约是 \(O(3^{n/3})\) ,可以通过
Luogu5982 [PA2019]Trzy kule
对于两个长为 \(n\) 的 \(01\) 串 \(a_i,\ b_i\) ,定义其距离 \(d(a,\ b)=\displaystyle\sum|a_i-b_i|\)
给定三个长为 \(n\) 的 \(01\) 串 \(s_1,\ s_2,\ s_3\) 和三个常数 \(r_1,\ r_2,\ r_3\) ,问有多少个长为 \(n\) 的 \(01\) 串 \(S\) 满足: \(d(S,\ s_1)\leq r_1,\ d(S,\ s_2)\leq r_2,\ d(S,\ s_3)\leq r_3\) 这三个限制至少有一个满足
答案模 \(10^9+7\)
\(n\leq10^4\)
先容斥成统计三个限制都不满足的字符串
我们用一些 \([0,\ 8)\) 间的二进制数 \(x_i\) 表示 \(s_1,\ s_2,\ s_3\) 三个串在这一位的状态,我们可以丢掉原串而仅考虑每种 \(x_i\) 的出现次数
注意到二进制数 \(k\) 和 \(k\) 的补集是等价的(可以改变 \(S_i\) 在这一位的 \(01\) 状态),不妨合并这两个二进制数。这一步也可以看作我们将 \(s_2\) 与 \(s_3\) 的每一位对应异或上 \(s_1\) 的每一位,并将 \(s_1\) 变为全 \(0\) 串
我们记 \(a_{0,\ 0}\) 为,有多少个 \(i\) 满足 \(s_{2,\ i}=s_{3,\ i}=0\) ;记 \(a_{0,\ 1}\) 为,有多少个 \(i\) 满足 \(s_{2,\ i}=0,\ s_{3,\ i}=1\) ; \(a_{1,\ 0},\ a_{1,\ 1}\) 同理
不妨对每个 \(a_{i,\ j}\) 枚举 \(x_{i,\ j}\) 表示,从这 \(a_{i,\ j}\) 个位中选 \(x_{i,\ j}\) 个,将其在 \(S_i\) 中对应的位置为 \(1\) ,其余的置为 \(0\)
那么原题限制相当于:
- \(0\leq x_{i,\ j}\leq a_{i,\ j}\)
- \(\displaystyle\sum x_{i,\ j}>R_1\)
- \(x_{0,\ 0}+x_{0,\ 1}+a_{1,\ 0}-x_{1,\ 0}+a_{1,\ 1}-x_{1,\ 1}>R_2\)
- \(x_{0,\ 0}+x_{1,\ 0}+a_{0,\ 1}-x_{0,\ 1}+a_{1,\ 1}-x_{1,\ 1}>R_3\)
而一组合法的 \(\{x_{i,\ j}\}\) 的贡献为 \(\displaystyle\prod\binom{a_{i,\ j}}{x_{i,\ j}}\)
不妨枚举 \(x_{0,\ 0}\) 和 \(x_{1,\ 1}\) ,那么对 \(x_{0,\ 1}\) 和 \(x_{1,\ 0}\) 的限制变为了:
- \(0\leq x_{0,\ 1}\leq a_{0,\ 1};\ 0\leq x_{1,\ 0}\leq a_{1,\ 0}\)
- \(x_{0,\ 1}+x_{1,\ 0}>t_1\)
- \(x_{0,\ 1}-x_{1,\ 0}>t_2\)
- \(x_{1,\ 0}-x_{0,\ 1}>t_3\)
可以用二维前缀和解决
注意到如果要开 \(n^2\) 的数组会比较难受,可以按照 \(x_{0,\ 0}+x_{1,\ 1}\) 升序枚举,这样 \(t_1\) 在枚举过程中是不增的,可以节省一维数组
时间复杂度 \(O(n^2)\)
auoj471 咕
你到了一个奖励关。奖励关里有 \(n\) 个房间,每个房间里有一个物品,第 \(i\) 个房间的物品价值为 \(v_i\) , \(v_{1..n}\) 组成一个随机排列
当你处于第 \(i\) 个房间时,你会获知 \(v_i\) 是否等于 \(1\) ,然后选择下列两种行动中的一种:
- 若 \(i<n\) ,移动到第 \(i+1\) 个房间
- 拿取第 \(i\) 个房间的物品,离开奖励关
你现在处于第 \(1\) 个房间,你想知道在最优决策下,你拿到了物品且你拿到的物品价值为 \(1\) 的概率
\(n\leq10^6\) ,数据组数 \(\leq10^5\)
记 \(f_i\) 为仅考虑排列后 \(i\) 个元素,取到 \(1\) 的概率
首先 \(v_i\) 有 \(\frac 1i\) 的概率是前缀最小值,如果此时选择离开,有 \(\frac in\) 的概率取得 \(1\) ,而不离开而取到 \(1\) 的概率为 \(f_{i+1}\) ;若 \(v_i\) 不是前缀最小值,取到 \(1\) 的概率为 \(f_{i+1}\)
因此有
初值为 \(f_{n+1}=0\)
将 \(\max\) 拆开,若 \(\frac in<f_{i+1}\) ,则 \(f_i=f_{i+1}\) 。而由于 \(\frac in\) 单增,则 \(f_i\) 的一段前缀权值相等,后一段单减
对于后一段的转移,有 \(\displaystyle f_i=\frac 1n+\frac{i-1}if_{i+1}\)
有 \(\displaystyle nf_i=1+\frac{n(i-1)}if_{i+1}\) ,不妨记 \(g_i=nf_i\) ,有 \(\displaystyle g_i=1+\frac{i-1}{i}g_{i+1}\)
可以发现 \(\displaystyle g_n=1,\ g_{n-1}=1+\frac{n-2}{n-1},\ g_{n-2}=1+\frac{n-3}{n-2}+\frac{n-3}{n-1}\) ,大力观察即可得到 \(\displaystyle g_i=(i-1)\sum_{j=i-1}^{n-1}\frac 1j\)
即 \(\displaystyle f_i=\frac{i-1}n\sum_{j=i}^{n-1}\frac 1j\) ,不妨假设在 \(i=d+1\) 处有 \(\displaystyle\frac{d}{n}\leq f_d\)
即
只需对于每个 \(n\) 预处理最大的 \(d\) 即可 \(O(1)\) 求出答案 \(f_d\)
(实际上答案在 \(d=\frac ne\) 左右取到是一个经典结论,调整一下精度说不定就莽过去了(
LOJ6066「2017 山东一轮集训 Day3」第二题
对于一棵有根树,定义一个点 \(u\) 的 \(k-\)子树 为 \(u\) 的子树中距离 \(u\) 不超过 \(k\) 的部分。若 \(u\) 子树内不存在与 \(u\) 距离等于 \(k\) 的点,则 \(k-\)子树 不存在
定义两棵子树是同构的,当且仅当不考虑点的标号,且考虑儿子间的相对顺序时,它们的形态是相同的
给定一棵以 \(1\) 为根的有根树,找到最大的 \(k\) ,使得存在两个点 \(u\neq v\) 满足 \(u\) 的 \(k-\)子树 与 \(v\) 的 \(k-\)子树相同
\(n\leq10^5\)
做法一:
二分 \(k\) ,考虑如何快速对 \(u\) 的 \(k-\)子树 求 hash 值
可以将其 \(k-\)子树 内所有节点按 \(dfn\) 序升序拿出来,将每个点度数作为其 hash 值
可以用 \(dep\) 和 \(dfn\) 两维限制确定一个点的 \(k-\)子树 点集
注意到固定 \(k\) 后,每个点 \(k-\)子集 的 \(dep\) 区间的长度是固定的,不妨将所有点按照 \(dep\) 升序考虑,用线段树维护当前点对应的 \(dep\) 区间中的点的 \(dfn\) 取值的 hash
时间复杂度 \(O(n\log^2n)\)
做法二:
倍增并 hash 处理所有点的 \(2^k-\)子树 的相等集合,用倍增数组二分即可,时空复杂度 \(O(n\log n)\)
做法三:
二分 \(k\) ,考虑求出 \(k-\)子树 的括号序的 hash,对于点 \(u\) ,其 \(k-\)子树中每个叶子都会将原本 \(u\) 子树的括号序分为两部分,我们可以暴力找到这些叶子即可,而每个点只会对其 \(k\) 级祖先贡献一次,时间复杂度 \(O(n\log n)\)
LOJ6479「ICPC World Finals 2017」小小水管工 Son of Pipe Stream
给一张带边权无向图,有两种液体 \(A,\ B\) 。每单位 \(A\) 液体需要花费 \(1\) 单位流量,每单位 \(B\) 液体需要花费 \(V\) 单位流量(流量为实数)
对于一条边 \((u,\ v,\ w)\) ,假设其分别流过了 \(a,\ b\) 单位 \(A,\ B\) 液体,你需要保证 \(a+bV\leq w\) 并且这两种液体的流向相同
液体 \(A\) 的源点为 \(1\) , \(B\) 的源点为 \(2\) , \(A,\ B\) 的汇点为 \(3\) 。找到一种流,记 \(F,\ W\) 分别为 \(A,\ B\) 液体的流量,最大化 \(F^aW^{1-a}\) ,其中 \(a\) 是一个给定的 \((0,\ 1)\) 间的实数。输出一种方案
\(n\leq200,\ m\leq\frac{n(n-1)}2\)
将 \(B\) 液体需要花费的流量看作 \(1\) ,那么得到的流量 \(W'=W\cdot v\)
先求出仅有一种液体时的最大流的流量 \(S\) ,可以证明,对于任意 \(0\leq F\leq S\) ,均存在一种构造方案使得 \(A,\ B\) 液体的流量分别为 \(F,\ W'=S-F\)
那么三分出 \(F^{a}(S-F)^{1-a}\) 的最大值,跑四遍最大流并输出方案即可
输出方案时,先考虑以 \(1,\ 2\) 为起点时的流量网络为基本,再以 \(1\) 为起点跑一边,剩下的流量即为 \(2\) 的答案
LOJ6158 A + B Problem
给定一个数字串 \(S\) ,选一个位置将其截成非空的两半,最大化两个新数的和的末尾 \(0\) 的个数
\(n\leq10^6\)
假设前 \(i\) 位被划到了第一部分,能够与每一位 \(j\) 的和为 \(0\) 的数码是确定的 \(10-S_j-[i\neq j]\)
我们记这样的目标串为 \(T\) ,那么问题就变为,求 \(T\) 的每个前缀与 \(S\) 的最长公共后缀长度,exkmp 即可
LOJ3403「2020-2021 集训队作业」function
记 \(P(x)\) 表示满足 \(1<y<x,\ y^3\equiv 1\pmod x\) 的 \(y\) 的数量
求 \(\displaystyle\sum_{i=1}^n[P(i)=m]\)
\(n,\ m\leq10^{10}\)
大力打表可以发现当且仅当 \(m\) 形如 \(3^k-1\) 时答案可能非 \(0\)
进一步地,通过 oeis 可以发现
其中 \(\displaystyle\prod p_i^{c_i}\) 是 \(x\) 的唯一分解
记 \(m=3^k-1\) ,我们只需要求有多少个 \(x\) ,其指数之和等于 \(k\) 即可,而 \(3^2\times5\times7\times11\times13\times17\times19\times23=334639305\) ,指数最多为 \(8\)
考虑用 min_25 筛这个东西
记 \(F(i,\ j,\ k)\) 为( \(\displaystyle i=\lfloor\frac nd\rfloor\)),前 \(i\) 个正整数中,质数和最小质因子大于第 \(j\) 个质数 \(p_j\) 的所有数中,其 \(3\) 的指数为 \(k\) 的方案数; \(G(i,\ j,\ 1/2)\) 为( \(\displaystyle i=\lfloor\frac nd\rfloor\)),前 \(i\) 个正整数中,最小质因子大于 \(pri_j\) 的合数和质数中,模 \(3\) 余 \(1\) 或 \(2\) 的数的个数
转移有
而初值有 \(F(i,\ |p|,\ 0)=G(i,\ |p|,\ 2)+1,\ F (i,\ |p|,\ 1)=G(i,\ |p|,\ 1)\) ,需要特判质数 \(2,\ 3\)
一道题
维护 \(n\) 个集合 \(S_i\) ,支持区间插入一个元素,询问区间每个集合 \(\text{mex}\) 的最大值
\(n\leq2\times10^5;\ q\leq10^5\)
考虑枚举答案,转化为判定某个集合中是否出现过数 \(x\)
不妨对 \(x\) 建立一棵序列线段树 \(T(x)\) ,每次操作将一段区间赋值为存在,直接查询即可
考虑合并所有线段树
我们给线段树 \(T(x)\) 上的每个节点标记一种颜色:
- 黑色,该节点被一些区间的并完整覆盖
- 灰色,该节点与某些操作相交但没有被完全覆盖
- 白色,该节点不与任何操作相交
给线段树加一个颜色为灰色的虚根,那么根到任意叶子 \(u\) 的路径都满足:先经过一段灰色点,剩下的点均为黑色或白色
那么叶子 \(u\) 对应的集合不存在元素 \(x\) 当且仅当 \(u\) 到根的路径中存在一个点 \(anc\) 满足:点 \(anc\) 颜色为白,其父亲颜色为灰。我们称满足这种条件的点 \(anc\) 为关于 \(x\) 的关键点
初始时每个线段树仅有实根为关键点,考虑修改带来的变化。不妨假设所有操作是互不相交的
对于与修改区间有交的线段树节点对应的区间 \([l,\ r]\) ,它修改后不可能是关键点,且有以下几种情况:
- 如果被修改区间完全包含,可以发现修改之前这个区间是白色的,返回即可
- 如果修改区间只涉及到其左右儿子之一,向那个儿子递归,如果另一个儿子是白色,则它在修改后是关键点
- 向两个儿子递归
可以发现关键点总数是 \(q\log n\) 级别的
考虑询问,单个集合的答案就是所有其对应线段树叶子到根的路径上存在关键点的 \(x\) 的最小值,需要在修改的时候维护子树内的这玩意儿
至于如何让所有修改不相交,对于每个 \(x\) 随意用普及组算法拆一下即可
时空复杂度 \(O((n+q)\log n)\)
皮克定理
格点三角形面积 \(S=a+\frac12b-1\) ,其中 \(a\) 是严格落在三角形内的格点数, \(b\) 是落在三角形边界上的格点数