2023 年 6 月训练记录

训练

中考终于考完了!!!

前面的题慢慢施工ing……

ARC107F Sum of Abs

首先,我们现默认所有节点都被删了,可以用 \(A_i\) 的收益插入第 \(i\) 个节点。由于是求最大值,所以绝对值可以看作是限制有边的点同号。

我们考虑建图,对于第 \(i\) 个点,我们建两个点 \((i,-)\)\((i,+)\) 表示取负或取正,每个点有点权,则 \((i,-)\)\((i,+)\) 连边表示不能同时选。

对于一条边 \((u,v)\)\((u,-)\)\((v,+)\)\((u,+)\)\((v,-)\) 连边表示不能同时选。

于是跑二分图最大独立集即可。

时间复杂度 \(O(n^2(n+m))\)

记录

ARC083F Collecting Balls

对于球 \((a,b)\),将点 \(p_a\)\(q_b\) 连边,表示这个球需要被行或列碰撞。则要求连出来必须是基环树森林,否则无解。

因为点数为 \(2n\),边数为 \(2n\)。若不全为基环树森林,则连通块中一定存在树,边数 \(<\) 点数,不可能存在完美匹配。

然后考虑对每棵基环树分开考虑,首先,树的部分边的方向是确定的,而环上只有两种情况。我们直接枚举,然后我们建出图,表示机器启动的先后关系(某台机器必须在某台机器后启动)。

注意到这个 DAG 一定是外向森林,所以拓扑序的方案数为 \(\frac{|S|!}{\prod_{i\in S} sz_i}\)

时间复杂度 \(O(n)\)

记录

[AHOI2022] 山河重整

首先,有个比较显然的结论,\(1,2,\cdots,n\) 都能被表示出来当且仅当,将 \(S\) 从小到大排序,\(\forall i\in [1,n], \sum_{j=1}^{i-1}S_j\ge S_i-1\),可以通过归纳来证。

然后我们考虑如何计数,首先有个暴力 DP,令 \(f_{i,j}\) 表示用前 \(i\) 的数表示出的和为 \(j\) 的方案数。这没有什么前途。

我们考虑容斥,我们记 \(f_i\)\(i\)\([1,i]\) 合法的方案数,DP 初值可以用类似经典方法优化,时间复杂度 \(O(n\sqrt{n})\)

注意到和为 \(n\) 的数中不同个数是 \(O(\sqrt{n})\) 的。

如上图,每一列代表我选的数的值,注意到一种情况合法的充要条件:下面的行对应的列数 \(\in[\) 上面的行对应的列数 \(,\) 上面的行对应的列数 \(-1]\)

于是我们枚举当前行对应的列数 \(i\),无限背包转移大小为 \(i\) 的物品。

然后我们考虑转移,对于 \(f_i\),我们枚举第一个不合法的位置 \(j+1\),那么相当于要用 \([j+2, i]\) 的数凑出 \(i-j\) 的方案数再乘上 \(f_j\)

于是,我们可以用和上面一样的方法,不过对于 \(f_j\),背包内的物品大小至少为 \(j+2\)

注意到计算 \(f_i\) 时,我们必须把之前的 DP 值提前计算完成。这里可以使用类似半在线卷积,每次先求出前一半的 DP 值,再转移给后一半。

时间复杂度 \(O(\sum_{i=0}\frac{n}{2^i} n \sqrt{n})=O(n\sqrt{n})\)

记录

[BJOI2019] 删数

本题是 AGC017C 的加强版。

我们沿用之前的做法,我们将出现了 \(c\) 次的数 \(x\),变成 \(x,x-1,\cdots,x-c+1\),而本题由于有整体加减 \(1\) 的操作,所以可能会出现数 \(<1\)\(>n\),则需要把他们的贡献删除。

时间复杂度 \(O(n\log n)\)

记录

CF1810F M-tree

我的贪心做法不能套到这题,伤心。

先二分答案 \(mid\),则现在变成了第 \(i\) 点深度至少为 \(d_i=mid-a_i\)

之前模拟赛出过一个题转化成了这一步,做法是维护一个堆,每次删去最大的 \(m\) 个叶子,然后加入这 \(m\) 个叶子中最小深度 \(-1\),然后把它放到值域上,就有一个递推式,不过这个递推式在本题非常不好维护。

我们考虑别的方法,类似得,我们注意到 \(m\) 个同一层的节点会占用一个上一层的节点,这很像 \(m\) 进制数的加法进位过程。

归纳下,就可以得到结论,满足条件当且仅当:\(\sum_{i=1}^{n} m^{-d_i}\le 1\)

也就是,\(\sum_{i=1}^{n} m^{a_i-mid}\le 1\),即 \(\sum_{i=1}^{n} m^{a_i}\le m^mid\)

然后,我们只需要线段树维护下这个 \(m\) 进制数即可。

时间复杂度 \(O(q\log n)\)

记录

[POI2014] SUP-Supercomputer

神仙结论题。

重要结论:树中存在一个深度 \(dep\),使得深度 \(\le dep\) 的点只需 \(dep\) 次覆盖完,而大于 \(dep\) 的除最后一次外其他每次都可以填充 \(k\) 次。

证明:在 \(dep\) 上面的所有点如果不能连续填充 \(k\) 次,说明均摊下来每一层的点数肯定小于 \(k\),这样的话一定存在上面的只用取 \(dep\) 次的深度,那下面层数均摊大于 \(k\),所以每次能填满 \(k\) 次,所以就是在找一个层数均摊为 \(k\) 的分界点,那么这种层数一定存在。

然后就是一个对于每个 \(k\),求出 \(\max_i \{ i + \lceil \frac{sum_i}{k} \rceil\}\)

我的做法是现转成 double,然后就是一个朴素的斜率优化了。

记录

[USACO22DECP] Palindromes

首先,无解是好判的。

考虑对一个串 \(st_{[l,r]}\) 算答案,相当于把 1 两两匹配,设有 \(cnt\) 个 1,第 \(i\) 个 1 位置为 \(x_i\)。显然第 \(i\) 个 1 会和第 \(cnt-i+1\) 个 1 匹配,贡献为 \(|x_i+x_{cnt-i+1}-(l+r)|\)

然后,我们直接分长度奇偶,枚举 \(1\) 的匹配,注意到 \(l+r\) 对于同一种匹配,只会变化 \(O(n)\) 次,所以直接维护即可。

时间复杂度 \(O(n^2)\)

记录

ARC086F Shift and Decrement

注意到操作 A 次数是 \(\log\) 的,于是考虑直接枚举总共操作 A 了 \(cnt\) 次,然后考虑在第 \(i\) 次操作 A 后进行操作 B 相当于在第一次操作 A 前进行操作 B \(2^i\) 次。

于是,操作 A 总共只有 \(2\) 种:

  1. 在前 \(cnt\) 次操作 A 之前进行最多 \(1\) 次操作;

  2. 最后再进行若干次操作。

注意到种类 1 只会改变 \(\lfloor \frac{a_i}{2^{cnt}} \rfloor\) 二进制下的最后一位,且为 \(0\) 的是 \(a_i \bmod 2^{cnt}\) 排序后的一段前缀,于是考虑直接枚举。

注意到种类 2 是全局减 1,只会改变差分的第一项,而且可行的差分第一项是一个区间,所以,我们直接对差分数组开 map,然后求区间并即可。

记录

ABC304Ex Constrained Topological Sort

首先,由于对于每条边要满足 \(P_{s_i}<P_{t_i}\),所以我们可以让 \(R_{s_i}=\min\{R_{s_i},R_{t_i}-1\}\)

然后,我们就从小到大枚举点,每次度为 \(0\) 且可以填的位置中 \(R\) 最小的。

证明:

时间复杂度 \(O(n\log n)\)

记录

CF618F Double Knapsack

高考题。

考虑先将选子集转化成选区间。

如果 \(sum_{a_n}<sum_{b_n}\),则交换下 \(a\)\(b\)

对于每个 \(i\) 找到最大的 \(pos\) 满足 \(sum_{b_{pos}} \le sum_{a_i}\),那么 \(sum_{a_i}-sum_{b_{pos}}\in [0,n-1]\)

这样的 \(i\in[0,n]\)\(n+1\) 种,所以根据抽屉原理一定能找到两个相同。

时间复杂度 \(O(n)\)

记录

CF566E Restoring Map

做了半年,以下做法完全是自己想的,可能做烦了。

首先,现特判下菊花,以及两个点接所有叶子的情况。

我们对任意两个集合求交,那么对于一条边上的两个点,得到的集合为两个点和其有边点集的并,且集合大小至少为 \(3\),对于其它情况要么为空,要么为一个点,要么为一个点和其有边点集。

对于一个点和其有边点集的情况,这样的情况要么大小为 \(2\),要么出现多次。

那么现在,我们得到了一条边上两个点和其有边点集的并,我们考虑如何还原出这条边。首先,在点集内的这些点与这个集合的交至少为 \(3\)(它本身和边的两个端点),于是我们再求出这些集合的交,不难发现恰好为边的两个端点。

不过还有种比较麻烦的情况,就是一条边有一个端点是叶子,这种情况下,两个点和其有边点集会退化成一个点和其有边点集。注意到叶子的集合会被它父亲以及它父亲相连点的集合包含(\(\ge 2\)),所以我们可以找出哪些集合是叶子。

然后如果这个点集内已经有边的点数量多于 \(2\) 的话,我们对边集取交,就可以唯一确定它们的中心了。

否则,这个点集内已经有边的点数量为 \(2\),由于判掉了两个点接所有叶子的情况,所以只有一个点非叶子的边只有一条。

于是就做完了!

使用 bitset 优化上述过程。

时间复杂度 \(O(\frac{n^3}{\omega})\)

记录

ABC229Ex Advance or Eat

超现实数板题。

对于不平等博弈,我们可以考虑用超现实数来解决,详见集训队论文。

struct Surreal {
	ll n;
	int d;
	Surreal(ll _n = 0, int _d = 0) { n = _n, d = _d; }
	inline friend Surreal operator + (const Surreal &x, const Surreal &y) {
		int mx = max(x.d, y.d);
		ll t = (x.n << (mx - x.d)) + (y.n << (mx - y.d));
		int v = min(mx, __builtin_ctzll(t));
		mx -= v;
		t >>= v;
		return Surreal(t, mx);
	}
	inline friend bool operator < (const Surreal &x, const Surreal &y) {
		int mx = max(x.d, y.d);
		return (x.n << (mx - x.d)) < (y.n << (mx - y.d));
	}
	inline friend bool operator > (const Surreal &x, const Surreal &y) {
		return y < x;
	}
	inline friend bool operator <= (const Surreal &x, const Surreal &y) {
		return !(y < x);
	}
	inline friend bool operator >= (const Surreal &x, const Surreal &y) {
		return !(y > x);
	}
	inline friend Surreal operator - (const Surreal &x) {
		return Surreal(-x.n, x.d);
	}
	inline friend Surreal operator | (Surreal x, Surreal y) {
		assert(x < y);
		if (x < 0 && 0 < y) return 0;
		if (y <= 0) return -(-y | -x);
		Surreal v((x.n >> x.d) + 1);
		if (v < y) return v;
		int d = max(x.d, y.d);
		x.n <<= d - x.d;
		y.n <<= d - y.d;
		if (x.n + 1 == y.n) return Surreal(2 * x.n + 1, d + 1);
		while ((x.n >> 1) + 1 < ((y.n + 1) >> 1)) {
			x.n >>= 1, y.n = (y.n + 1) >> 1;
			d--;
		} assert(x.n + 1 == y.n - 1);
		return Surreal(x.n + 1, d);
	}
};

这是板子。

我们对于 DAG 上的一条先手可以选择的决策求出超现实数最大值,对于后手可以选择的决策求出超现实数最小值,最后将其 | 起来即可。

然后注意到每列是独立的,我们再把每列得到的超现实数加起来,最后再根据与 \(0\) 的大小关系来判断先手获胜还是后手获胜。

时间复杂度 \(O(n^2 3^n)\)

记录

CF578F Mirror Box

首先,我们对图中 \((n+1)\times (m+1)\) 个点黑白染色,则一条边只会在黑点或白点之间。

重要结论:满足从任意一个边界段垂直射进网格中,光线会从相邻的边界段射出,同时网格中的每一段都被至少一条光线穿透,当且仅当黑点或白点连成一颗生成树。

首先,显然不能有环。其次要将边界上的边两两分成一组,每一组用一条封闭的折折线给围住,所以得连通。

于是,现将原图缩成一些连通块,然后再使用 \(Matrix-Tree\) 定理,求出生成树个数即可。

时间复杂度 \(O(nmα(nm)+k^3)\)

记录

基于值域预处理的快速 GCD

首先,任何一个数 \(x\) 可以被拆成 \(3\) 个数 \(a,b,c\) 每个数都满足以下至少一个条件:

  1. 为质数;
  2. \(\le \sqrt{n}\)

证明:考虑归纳,首先边界条件 \(1\) 是合法的。然后对于一个数 \(x\),令其最小质因子为 \(p\),我们先求出 \(\frac{x}{p}\) 的答案,令其从小到大排序为 \(a,b,c\)

\(p> n^{\frac{1}{4}}\),则 \(n\) 的质因子个数不超过 \(3\)\(\frac{n}{p}\) 的质因子个数不超过 \(2\),所以 \(a=1\)

\(p\le n^{\frac{1}{4}}\)。设 \(p=n^t\),则 \(ap\le n^t\times n^{\frac{1-t}{3}}=n^{\frac{2t+1}{3}}\),所以 \(\max_{ap}\)\(t\) 增加而增加,所以把 \(t=\frac{1}{4}\) 带入,可得 \(\frac{2t+1}{3}=\frac{1}{2}\)

一个数和一个质数的 \(\gcd\) 是好算的。然后,我们就预处理出 \(\sqrt{a_i}\) 中两两的 \(\gcd\),可以递推。

时间复杂度 \(O(n^2+a_i)\)

记录

[APIO2021] 封闭道路 CF1119F Niyaz and Small Degrees

感觉是比较套路的题,比较快地想出来了。

首先有个比较朴素的 DP,我们记 \(f_{i,j,0/1}\) 表示以 \(i\) 为根的子树,度数限制为 \(j\)\(i\) 是否能和父亲连边的最小权值。

考虑 DSU on tree,注意到对于一棵子树,\(f_{i,j,0}\)\(j\) 只有子树大小种,\(f_{i,j,1}\)\(j\) 只有 \(i\) 的度数种。

我们现继承重儿子的答案,然后对于轻儿子,我们先选择 \(f_{i,j,0}\),并将 \(f_{i,j,1}+edgeval-f_{i,j,0}\) 放入 \(Q_j\)\(Q_i\) 是一个堆。

那么我们处理 \(f_{x,i,0/1}\) 的时候,首先 \(Q_i\)\(<0\) 的一定选,然后再选择前若干个使 \(x\) 满足度数限制。

时间复杂度 \(O(n\log n)\)

记录 1

记录 2

CF1662J Training Camp

非常神仙的题。

我们考虑网络流。其中,源点连向所有填 \(1\) 的点,每个点连向同一行、同一列填入数比它大 \(1\) 的点,所有填 \(n\) 的点连向汇点。

则选 \(n\) 个点合法当且仅当 \(S\)\(T\) 不连通。

证明:

  1. 必要性:

    \(p_{i,j}\) 表示第 \(i\) 行值为 \(j\) 的列编号,\(q_{i,j}\) 表示第 \(i\) 列值为 \(j\) 的行编号。

    注意到一个值为 \(a\) 的不满足条件的点 \((i,j)\)(不妨假设所在行选的数比它大,所在列选的数比它小),一定会对应一条路径:\(S\to p_{i,1}\to \cdots\to p_{i,a-1}\to (i,j)\to q_{j,a+1} \to \cdots \to q_{j,n}\),不妨成其为 简单道路

    由于 \(S\)\(T\) 不连通,所以不存在这样的路径,所以方案合法。

  2. 充分性:

    \(S\)\(T\) 连通,则存在一条 \(S\)\(T\) 的路径。但这条路径中的边可能经过多个行或列。

    我们不妨假设,这条路径最后是连续在行上走。

    首先,我们设到这个最后一段的起点为 \((i,j)\),所以第 \(i\) 行所删除的数小于 \(a_{i,j}\)

    现在,我们对第 \(j\) 列所删的数分类讨论:
    1. 如果删除的数大于 \(a_{i,j}\),那么说明 \((i,j)\) 这个位置不合法;
    2. 如果删除的数小于 \(a_{i,j}\),则可以把路径上的这一段删除,改为从 \((i,j)\) 在第 \(j\) 列一直走到头。

    所以,对于这条路径,我们要么会得证,要么会减少一个拐点,最后只剩下一个拐点时就变成了一个点时,这条路径就退化成了一条 简单道路,则一定是情况 1。

    得证。

实现的时候把每个点拆开,于是删点就变成了删边,那么跑最小割即可。由于要确保只能删 \(n\) 的点,所以,我们在原图一个点拆成的两点之间连边权 \(2n-b_{i,j}\) 即可。

时间复杂度 \(O(n^6)\),由于是 dinic,所以 \(O(能过)\)

记录

CF1168E Xor Permutations

dls /bx

邓老师的论文例题。

考虑使用调整法,我们每次随机选一个未匹配的点,若存在它的一条匹配边满足另一个点也未匹配,则得到这样一组匹配;否则,我们随机它的一条边,强制其匹配,并将原先的匹配边断开。

实测非常优秀。

时间复杂度 \(O(能过)\)

记录

CF1285F Classical?

很巧妙的题,没能想出来。

我们可以将每个数的因数都加进去,这样,我们就把原问题转化为了计算 \(\max\limits_{a_i\perp a_j}a_ia_j\)

我们从大到小加入数,同时维护一个栈,从栈顶到栈底递增。由于若存在 \((x,y)\) 的答案,则对于 \(a<x, b<y\) 的答案 \((a,b)\) 就不需要统计了。

那么,若当前栈内有数与 \(a_i\) 互质,则可以弹出栈顶,并更新答案。

判断栈内是否有数与 \(a_i\) 互质,可以使用莫比乌斯反演:

\[\sum_{d|a_i} \mu(d)cnt_d \]

\(cnt_d\) 表示栈内 \(d\) 倍数数的个数。

时间复杂度 \(O(n\log n)\)

记录

CF1510H Hard Optimization [FJOI2022] 区间子集问题

由于保证 \(n\) 条线段中,任意两条线段要么一个包含另一个,要么不交,则可以将包含关系建成一棵树的形式。

对于子树根 \(x\),它的子段有两种情况:

  1. 在两个相邻儿子之间;
  2. 在一个儿子的内部。

对于情况 1,我们用坐标差来算;对于情况 2,我们考虑加一维状态,将贡献提前算。

我们设状态 \(f_{i,j,0/1,0/1}\) 表示 \(i\) 的子树内已经预留了 \(j\) 个子段,并且算进了答案。

\(1\) 个 0/1:若为 \(1\) 表示左端点带上了 \(-1\) 的系数算进了答案;
\(2\) 个 0/1:若为 \(1\) 表示右端点带上了 \(1\) 的系数算进了答案。

于是就可以转移了。

时间复杂度 \(O(n^2)\)

记录

动态图连通性

很巧妙的题,没能想出来。

首先,一条边被询问多次,要么是第一次被删,要么是一直没被删,于是我们对每个点 \(i\)\(tim_i\) 表示 \(i\) 号点第一次被询问的标号,若不存在则为 \(\infty\)

重要观察:询问相当于是让我们离线,找到一条按 \(tim\) 排好序后字典序最大的路径。因为,能删就删,所以我们首先要求让最小值最大,然后要求次小值最大,依此类推。

首先,我们有个很无聊的暴力做法就是建主席树,然后哈希比较字典序,时间复杂度 \(O(n \log^2 n)\)

当然,我们有一个非常简单的做法,我们令 \(P_i\) 是从 \(1\)\(i\) 最优路径集合,那么按照 dij,我们通过边 \((u_t=i,v_t)\)\(P_i\) 更新 \(P_{v_t}\),我们要按照 \(P_i+\{tim_t\}\) 来排序,但现在我们有个结论是,我们只需要按照 \(tim_t\) 排序即可。

证明:考虑 dij 过程中的两种转移 \(P_i+\{a\}\)\(P_j+\{b\}\)。不妨假设 \(P_i<P_j\)。由于这两种转移同时存在,所以根据 dij,得到 \(P_i+\{a\}>P_j\),那么说明 \(a>\max_{k\in {P_i\cap P_j}} k\)

由于 \(a!=b\),所以在比较 \(P_i+\{a\}\)\(P_j+\{b\}\) 时,\(<a\) 的元素可以忽略。于是,忽略后 \(P_i=P_j\),所以等价于比较 \(a\)\(b\) 的大小关系。

时间复杂度 \(O(n\log n)\)

记录

CF1832F Zombies

相当于是最大化 \(\sum |I_i\cap J_{P_i}|\)

首先,我们把区间按照中点排序。

相当于是对原序列划分成 \(k\) 个区间,每个区间 \(g_{i,j}\) 答案是确定的。

我们考虑如何求出 \(g_{i,j}\),表示对 \([i,j]\) 这个区间内的区间与一个区间交总和的最大值。注意到 \(J_i\) 的左端点一定在 \(\{l_i,r_i-x\}\) 中,只有 \(O(n)\) 中。

显然,\(g_{i,j}\) 满足决策单调性,所以可以 \(O(n^2)\) 预处理出来。

然后,我们记 \(f_{i,j}\)\(i\) 个区间被分成 \(j\) 个区间的最大值,同样用决策单调性优化即可。

时间复杂度 \(O(n^2)\)

记录

CF241D Numbers

逆天题,想了很久不会。

观察发现把一串数字接起来是一个类似随机的事情。

再是由于模数 \(P\) 很小只有 \(5\times 10^4\) 的范围,所以我们可以考虑只选用少量的数字。

经过实践,发现留下 \(1~24\)就足够了,这样选取也能使异或和 \(=0\) 的方案足够的多。

最后直接 \(2^{24}\) DFS所有子序列即可。

记录

ExPR 1 乘积 ABC239Ex Dice Product 2

原来这就是 CF1801F 的原题,赛时一直不会,自闭了。

考虑把操作倒过来,\(x\times y>M\) 在自然数意义下当且仅当 \(x>\lfloor\frac{M}{y}\rfloor\)

于是,我们先数论分块把本质不同的 \(\lfloor\frac{M}{i}\rfloor\) 求出来,然后从小到大暴力 DP,每次也是数论分块求出整除后的数即可。

时间复杂度 \(O(n^{\frac{3}{4}})\)

记录

ABC304G Max of Medians

首先,我们二分中位数 \(mid\),我们把数建成 Trie。

一个重要的观察是:注意到 \(xor\) 的时候,\(LCA\)\(xor\) 的最高位,所以说 \(LCA\) 越浅,\(xor\) 越大。

所以,我们的思路是尽可能在子树内匹配。

我们分两类 DP:

  1. 一类是子树内匹配,设为 \(f_x\) 表示 \(x\) 子树内尽可能匹配,最少还剩多少个数没有匹配:

    我们考虑优先在子树内匹配,因为跨子树匹配一定比子树内匹配优,也就是说我们求出了每棵子树剩下的数个数的下界,中间相差 \(2\) 的都可以取到。

    根据 \(x\) 的二进制位来分类讨论:

    1. 若当前位为 \(1\),则递归到两组子树跨子树匹配,进入情况 2,\(g_{x_{ls},x_{rs}}\)
    2. 若当前位为 \(0\),则递归到两棵树内分别先内部匹配,进入情况 1,\(f_{x_{ls}}\)\(f_{x_{rs}}\)
  2. 另一类是两棵不同子树的最大匹配,设为 \(g_{x,y}\) 表示 \(x\) 子树和 \(y\) 子树内尽可能交叉匹配,最少还剩多少个数没有匹配:

    根据 \(x\) 的二进制位来分类讨论:

    1. 若当前位为 \(1\),则递归到两棵子树的 \(0\)\(1\),进入情况 2,\(g_{x_{ls},y_{rs}}\)\(g_{x_{rs}},g_{x_{ls}}\)
    2. 若当前位为 \(0\),则递归到两棵子树的 \(0\)\(1\) 先内部匹配,进入情况 2,\(g_{x_{ls},y_{rs}}\)\(g_{x_{rs}},g_{x_{ls}}\),然后再讲剩下的尽量匹配。

最后求出最大匹配。

容易发现,过程中每个字典树节点只会被经过一次。

时间复杂度 \(O(n\log^2 a)\)

记录

AGC012E Camel and Oases

注意到操作 \(2\) 的次数是 \(\log\) 的,且每次操作 \(1\) 都会把能走到的都走到。

我们先预处理出 \(p_{i,j}\) 表示做了 \(i\) 次操作 \(2\) 时,\(j\) 能往后最远到的位置、\(q_{i,j}\) 表示做了 \(i\) 次操作 \(2\) 时,\(j\) 能往前最远到的位置。

注意到我们最终相当于将 \(0\sim \log D\) 分配给一些位置,满足分成的区间内都可以互相到达。

那么我们就记 \(f_{S}\) 表示分配的操作 \(2\) 状态为 \(S\),能从 \(1\) 开始往后覆盖的最远距离,\(g_{S}\) 表示分配的操作 \(2\) 状态为 \(S\),能从 \(n\) 开始往前覆盖的最远距离。

然后,判断 \(i\) 就相当于判断是否 \(\exists S,f_{S}\ge i\ge g_{\{1,2,\cdots,\log_2 V\}\backslash S}\)。用差分,前缀和维护一下即可。

记录

CF1842G Tenzing and Random Operations

非常高妙的题!

考虑乘法分配律 \(\prod a_i+kv\)

我们记 \(f_{i,j}\) 表示现在已经计算出了前 \(i\) 个数的答案,限制了 \(j\)\(v\) 的放置的答案。

然后,我们对乘法分配律选到的数分类讨论:

  1. \(a_i\)\(f_{i-1,j} a_i\to f_{i,j}\)
  2. 之前选过的 \(v\)\(f_{i-1,j-1} jv\to f_{i,j}\)
  3. 新选过的 \(v\)\(f_{i-1,j} (m-j)v\to f_{i,j}\)

时间复杂度 \(O(n^2)\)

记录

CF1842H Tenzing and Random Real Numbers

我们令 \(p_i=x_i-0.5\),则 \(x_i+x_j>1\) 的限制变成了 \(p_i+p_j>0\),也就是变成了 \(p_i> -p_j\)

我们观察到这只与 \(|p_i|\) 的大小关系和 \(p_i\) 的正负有关。

下面假定 \(|p_i|<|p_j|\)

  1. \(p_i>-p_j\)

    \(p_i\) 无限制,\(p_j\) 为负。

  2. \(p_i<-p_j\)

    \(p_i\) 无限制,\(p_j\) 为正。

于是,我们考虑 DP,令 \(f_{S}\) 表示 \(|p_i|\)\(|S|\) 大为 \(S\),每次加入新数时判断是否可以去正、负即可。

记录

ARC162E Strange Constraints

简单题,但 VP 没过,鉴定为 🤡。

我们直接 DP,令 \(f_{i,j,k}\) 表示已经选了出现次数 \(\ge i\) 的数,不同数的个数为 \(j\),总数为 \(k\)。然后,我们枚举选 \(l\) 个出现次数 \(=i\) 的数来转移,中间需要用到组合数和斯特林数。

分析下时间复杂度,\(j\) 的个数最大为 \(\lfloor\frac{n}{i+1}\rfloor\)\(l\) 的个数最大为 \(\lfloor\frac{n}{i}\rfloor\),所以总复杂度为:

\[\sum_{i=1}^{n} n\lfloor\frac{n}{i+1}\rfloor\lfloor\frac{n}{i}\rfloor\le n^3\sum_{i=1}^{n}\frac{1}{i(i+1)}=\frac{n^4}{n+1}\le n^3 \]

倒数第二步用到裂项法计算。

时间复杂度 \(O(n^3)\)

记录

PR 5 双向奔赴 QOJ3301 Economic One-way Roads

一个强连通分量一定可以由如下过程产生:

  1. 初始有一个集合 \(S\),只有一个点。
  2. 每次加入一条链 \(a_1,a_2,\cdots,a_k\),要求 \(a_i,a_{i+1}\)\(1\le i<k\))之间有边,并且只有 \(a_1,a_k\in S\)

考虑 \(f_{S}\) 表示集合为 \(S\) 的最小代价,\(g_{S,x,y}\) 表示链的点集为 \(S\)\(a_1=x,a_k=y\) 的最小代价。

注意到 \(a_1\) 可以 \(=a_k\),但这是我们要求 \(|{a_1,a_2,\cdots,a_k}|>2\)

时间复杂度 \(O(2^nn^3)\)

记录

PR 9 比赛 QOJ1431 Joy

模拟下发现,比赛整体是一个满二叉树的结构。我们可以先预处理出小多在最左侧、最右侧的答案,相当于求出小多在整个子树左侧、右侧的答案。

记状态 \(f_{0/1_{i,j}}\) 表示 \(i\) 子树内 \(j\) 分上述两种情况最终留下的概率。

求答案的时候考虑只有 \(\log\) 棵子树被影响到,其他都可以用预处理好的值进行计算。

时间复杂度 \(O(n^2)\)。首先考虑预处理,由于是个树形背包的复杂度,每两个点之后在 LCA 出被计算一次,而总共只有 \(2n-1\) 个点,所以是 \(O(n^2)\) 的。考虑求值部分,单次查询,所有使用预处理子树的大小和为 \(1+2+\cdots+\frac{n}{2}=n-1\),所以是 \(O(n^2)\) 的。

记录

posted @ 2023-06-22 13:58  zhaohaikun  阅读(155)  评论(0编辑  收藏  举报