最近感觉自己思维僵化,啥都不会做了……

Distance Sums

题意

给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树。满足第 \(i\) 个点到其他所有点的距离和为 \(D_i\)

\(n \le 10^5\)

技巧

寻找特殊的量,推出整个树的形态

题解

题解 整棵树里头,最为特殊的点有两类。一个是重心,这是距离和最小的点,另一个是叶子节点,这是距离和最大的节点。考虑如果我们先确定重心,那么接着就不大好往下推了,因为我们并不知道子树的大小。考虑从叶子节点往上推,记录当前子树的大小,这样我就可以直接得到父亲节点的距离和。由于题目保证了所有点的距离和各不相同,因此我可以直接确定这个点的父亲。注意往上一直推到根节点之后,还需要检查一遍根节点的距离和是不是正确的。因为我们这么做只保证了相邻节点的距离和的差值的正确性。

Ribbons on Tree

题意

给定一棵 \(n(n \equiv 0 \bmod 2)\) 个节点的树,你需要将这 \(n\) 个节点分成 \(\frac{n}{2}\) 组,每组两个节点。这 \(\frac{n}{2}\) 组点对会形成 \(\frac{n}{2}\) 条路径。求有多少种不同的分组方案,使得树上每条边都至少被其中一条路径覆盖。

\(n \le 5000\)

技巧

利用容斥原理简化限制。

题解

题解 直接 DP 只能做到 $O(n^3)$ 的复杂度。直接 DP 大概就是设 $dp_{i,j}$ 表示 $i$ 号点的子树,孩子到父亲的边被 $j$ 条边覆盖的方案数。由于合并的时候必须要枚举多少条链相接,因此复杂度会来到 $O(n^3)$ 。

考虑容斥,那么这棵树可以视作断成若干个联通块,联通块内随意配对。这样如果直接做 \(n\) 遍 DP ,仍然是 \(O(n^3)\) 的,因为你需要做 \(n\) 次 DP,每次 DP 仍然需要记一个当前子树大小。

考虑做 \(n\) 遍 DP 有一些浪费,能不能把容斥融到 DP 里头呢?答案是可以的。你只需要在选择断掉一条边的时候,乘上一个 \(-1\) 的转移系数就可以了。

Robots and Exits

题意

数轴上有 \(n\) 个机器人和 \(m\) 个出口。每次你可以对 \(n\) 个机器人的坐标同时 \(+1\)\(-1\) 。当一个机器人的位置上恰好有一个出口的时候,机器人就会从出口消失。求有多少种不同机器人走出出口的方案数。两种方案不同,当且仅当一个机器人从不同的出口消失。

\(n \le 10^5\)

技巧

巧妙建模转化题目

题解

题解 首先每个机器人只会从他左右两个出口消失。考虑将每个机器人抽象成二维平面上的一个点,这个点的横坐标表示这个机器人距离左边出口的距离,纵坐标表示这个机器人距离右边出口的距离。那么一个方案就可以抽象成从 $(0,0)$ 出发至 $(\infty,\infty)$ 一条轮廓线。这条轮廓线左上角的机器人即从左边出口消失,否则从右边出口消失。于是我们只需要统计轮廓线的方案数。

考虑轮廓线如何统计不会记重。设 \(dp_i\) 表示经过第 \(i\) 个点的轮廓线方案数。那么接下来合法的转移点为第 \(i\) 个点右上角的所有点,表示轮廓线先向上走一段,再向右走剩下的一段。DP 可以用树状数组优化。时间复杂度 \(O(n \log n)\)

Colorful Sequences

题意

给定一个长度为 \(m\) ,字符集大小为 \(k\) 的母串。求所有满足以下条件的字符串中母串出现次数之和。

  1. 该字符串的长度为 \(n\),字符集大小为 \(k\)
  2. 这个字符串至少包含一个子串满足这个子串是一个 \(1\)\(k\) 的排列。

\(m \le n \le 25000,k \le 400\)

技巧

考虑母串对答案的贡献。

题解

题解 母串在某个串的出现次数,如果使用字符串的思路,会非常不好做。考虑母串对答案的贡献,如果我们确定了母串在最终字符串的出现位置。那么抛开第二条限制,母串两边的位置就可以随意填了。

考虑加上第二条限制之后该怎么做。如果母串中包含了两个相同的字符,那么这个 \(1\)\(k\) 的排列一定不会跨过母串。所以这个排列一定会出现在母串的两侧。只要计算出母串从左右两侧出发的极长不重复序列的长度,就可以向左向右分别 DP 了。DP 大概就是记 \(dp_{i,j}\) 表示当前考虑到第 \(i\) 个字符,从第 \(i - j + 1\) 个位置到第 \(i\) 个位置各不相同,且第 \(i\) 个位置和第 \(i-j\) 个位置相同的方案数。DP 利用前缀和可以做到 \(O(nk)\) 的复杂度。

如果母串中包含的字符各不相同,那么每个字符都是等价的。考虑将所求转化为,求出满足条件的字符串中,包含了长度为 \(m\) 且这 \(m\) 个字符互不相同的子串出现次数之和,最后只需要将答案除一个 \(\binom{k}{m}m!\) 。计算的过程可以用类似第一种情况的一个 DP 解决。需要多记一维表示是否合法,多记两个数组表示出现次数之和。

注意如果这个母串如果包含了一个 \(1\)\(k\) 的排列,需要特判一下。

代码长度 \(\texttt{3.4Kb}\) 的 DP 题……

Eating Symbols Hard

题意

给定一个长度为 \(n\) 的字符串,这个字符串由 +->< 四种字符。求这个字符串有多少子串的权值与原串相同。

一个字符串的权值定义为,按照顺序执行这个字符串的操作。+ 操作会对指针所在位置 \(+1\)- 操作会对指针所在位置 \(-1\)>,< 操作分别会将指针右移或左移。指针最开始位于 \(0\) 处,两个字符串的权值相同当且仅当按照操作生成的数组每一位都相同。

\(n \le 250000\)

难得的会做的 F 题……

题解

题解 注意到两个字符串拼接之后的数组可以直接 $O(1)$ 合并,因此可以利用 Hash 解决。所以思路就比较简单了。只需要将每个前缀插到哈希表里头,然后对每个前缀去掉一个等长的前缀,再和母串匹配。去掉前缀可以转化为给母串加上一个前缀。因此只要对母串加上一个前缀,再到哈希表里头查就可以了。

Donation

题意

给定一张 \(n\) 个点,\(m\) 条边的图。这张图的每个点有两个权值 \(a_i,b_i\)。你将会从这张图中选出一个点作为起点,随后开始遍历这张图。你能到达一个节点 \(i\) 当且仅当你的手上有至少 \(a_i\) 元钱。当你到达一个节点 \(i\) 后,你可以选择对这个点捐赠 \(b_i\) 元。你需要对每个点捐赠一次。问你身上至少要带多少元钱?

\(n,m \le 10^5\)

技巧

太神了……都不知道技巧在哪里……

题解

题解 首先可以注意到两个性质

  1. 你一定会在最后一次经过某个点的时候对这个点进行捐赠。
  2. 定义 \(\max(a_i - b_i,0)\) 为这个点的权值,那么权值越大的点会尽量放到前面捐赠。

第一个性质比较显然,因为捐赠之后你手里的钱会变少。因此如果我们把捐赠放到最后一次经过那个点,方案不会更劣;考虑我们如果保证了第一条性质,我们会得到这样一个捐赠的方式:首先确定一个点,依次捐赠这个点的子联通块,留下一个子联通块,随后捐赠这个点,最后捐赠剩下的这个子联通块。

第二条性质的前提是第一条性质。即在满足第一条限制的前提下,再去尽量满足第二条性质。假设我们确定的这个点权值不是最大的,那么考虑交换这个点与权值最大的点,一定不会更劣。形象化地理解就是,如果我们把权值大的点放到前面,会给后面的点留下一定的空间,多花的权值会更少一些。如果想要形式化的理解,可以等会看 DP 的式子就能理解了。

得到了这两个性质,我们稍微理一下思路。每次从全局选择一个权值最大的点,断掉这个点会形成若干个联通块。接下来需要找出最后遍历哪个联通块是最优秀的。寻找这个最优秀的联通块可以利用 DP 来解决。一直这么递归下去就可以得到一棵树。到这里 DP 应该比较简单了,设 \(dp_i\) 表示 \(i\) 号点的子树需要多花的最少的钱数。那么就会有

\[dp_x = \min\{A_x,\max(dp_y,A_x - Sum_y)\} \]

其中 \(A_x\) 表示 \(x\) 的权值,\(Sum_x\) 表示 \(x\) 子树的 \(b\) 值之和。最后 \(dp_{rt} + Sum_{rt}\) 即为最后的答案。DP 不需要将树建出来,直接用个并查集维护一下即可。

Monochrome Cat

题意

给定一棵 \(n\) 个点的树,树上每个节点会有黑白两种颜色。有一只猫在树上走,它可以自由地选择起点。它可以对这棵树执行以下两种操作。

  1. 翻转它所在的节点的颜色,这需要花费 \(1s\)
  2. 走到一个和它当前位置相邻的节点,并翻转新节点的颜色,这需要花费 \(1s\)

问最少需要花费多少时间可以把这个树变为全黑的。

\(n \le 10^5\)

技巧

将路径连成环,考虑多余贡献

题解

题解 这题基本算是自己搞定的吧……

首先发现起点和终点自由确定是件很烦的事情。因此考虑将这条路径先连成一个环。这样我们可以直接得到环的最小答案。环的最小答案,即不多走任意一个黑点所形成的路径。于是我们可以定一个白点为根,将整棵子树均为黑色的子树删掉。这样环上答案即为树上的边数的两倍,加上需要调整的点数。一个点需要调整,当且仅当它经过度数次翻转之后,颜色为白色。

再考虑从这个环中删掉一条路径,显然需要删掉一条贡献最大的路径。发现将一个需要调整的点删去会减少 \(2\) 的贡献,否则贡献不会改变,于是只要在树上找直径即可。注意需要加上一些特判。

Everything on It

题意

一个拉面餐厅有 \(n\) 种配料,一碗拉面可以任意添加任意的配料,也就是说,一碗拉面可以添加 \(2^n\) 种不同的配料组合。一个人要来拉面餐厅买若干碗拉面。求他有多少中不同的方式,满足以下两个条件:

  1. 所有购买的拉面的配料各不相同
  2. 每种配料在所有购买的拉面中至少出现两次

\(n \le 3000\)

技巧

容斥原理简化限制,暴力容斥优化

题解

题解 这种限制容易让人想到容斥原理。如果直接暴力容斥,枚举至少 $i$ 种配料没有出现,至少 $j$ 种配料只出现一次,还需要枚举一维 $k$ 表示只出现一次的配料划分为了多少个集合。这样似乎是 $O(n^4)$ 的?反正我只会做到这个复杂度……可以得到部分分。

考虑枚举两维有些浪费,如果两维放到一起枚举,只容斥一维,会怎样呢?

枚举至少有 \(i\) 种配料出现不超过一次,再枚举这出现了一次的数划分为了 \(j\) 个集合,最后枚举出现了一次的个数 \(k\) 就会有一个这样的式子。

\[ans_i = (2^{n-i})^j2^{2^{n-i}}\binom{n}{i}\sum_{k=j}^iS(k,j) \binom{i}{k} \]

注意到 \(\displaystyle\sum_{k=j}^iS(k,j) \binom{i}{k} = S(i + 1,j + 1)\) ,因此这个式子可以 \(O(n)\) 求。

关于斯特林数这个式子,可以理解为,先多加一个标记数,将这 \(i + 1\) 个数划分为 \(j + 1\) 个集合,最后将这个标记数所在的集合删掉。

Sweet Alchemy

题意

给定一棵 \(n\) 个点的树和两个参数 \(D,X\),以及每个点的费用 \(v_i\) 。你需要给每个点定一个权值 \(w_i\) 。每个点的权值需要满足 \(w_{fa_i} \le w_i \le w_{fa_i} + D\) 。要求 \(\displaystyle \sum_{i = 1}^{n} w_iv_i \le X\) 并最大化 \(\displaystyle\sum_{i=1}^{n}w_i\)

\(n \le 50,X,D,v_i \le 10^9\)

技巧

对于种类比较少,权值比较大的多重背包特殊解法。

题解

题解 对树做一下差分,容易把原题转化为一个背包的模型。相当于你可以对一个点的子树加上一个小于等于 $D$ 的权值$w$,并产生 $w\sum v_i$ 的代价,要求最大化权值和。对于这种特殊的背包模型该如何处理呢?

在最开始学背包的时候,会有一个错误的想法:对于权值为 \(v_i\),代价为 \(w_i\) 的若干物品,我们计算出它们的性价比,贪心的选择其中性价比高的部分物品。这样之所以是错的,是由于物品不能分割,这样会有空闲的地方出现但又不能塞入更好的物品了。于是我们考虑:在什么样的情况下可以直接用性价比高的物品代替性价比低的物品呢?

考虑两个物品 \(v_i,w_i\)\(v_j,w_j\),其中 \(\frac{v_i}{w_i} > \frac{v_j}{w_j}\)\(i\) 物品的性价比高于 \(j\)。如果我们选择了 \(v_i\) 个物品 \(j\),不如直接更换成 \(v_j\) 个物品 \(i\)。这样权值是相等的,都是 \(v_i \times v_j\),但代价却更小:\(v_j \times w_i < v_i \times w_j\)。由此我们知道:在可以选择性价比更高的物品却没有选择的情况下,性价比低的物品最多选择 \(v_i−1\) 个。而这个 \(v\) 的范围是很小的,所以我们可以对于每一种物品都从其中拿出 \(min(n,D)\) 件来进行多重背包,剩下的贪心即可。

以上题解来自 Twilight_Sx‘s Blog

代码并没有写,感觉没啥意思。

Permutation Tree

题意

给定一棵 \(n\) 个点的树,要你构造一个字典序尽量小排列。要求通过排列构造的树与给定的树同构。

通过排列构造树的方式如下:

  • 如果 \(p_i = 1\) ,什么事也不做;
  • 如果 \(p_i \not= 1\) ,找到一个最大的 \(j\) 满足 \(p_j < p_i\) ,并连一条 \(i\)\(j\) 的边。

\(n \le 10^5\)

题解

题解 容易发现,这样构造出来的树一定是用链串起来的一堆菊花,因此直接做就可以了……字典序最小就从链的两端都求一遍,比较一下就可以了……

这也能出到 ARC 的 F ……

Normalization

题意

给定一个长度为 \(n\) ,由 a,b,c 构成的字符串。每次你可以选出两个相邻且不相同的字符,把这两个字符都变为未出现的那个字符。问通过任意次数这样的变换,可以得到多少个不同的字符串。

\(n \le 2 \times 10^5\)

技巧

寻找不变的量,大胆猜想性质。

题解

题解 首先直接给出结论。

首先对于 \(n \le 3\) 的情况,情况比较鬼畜,所以直接特判。

再特判掉 \(S\) 全部相同的情况,目标串 \(T\) 合法,当且仅当 \(T = S\) ,或者满足以下两个性质:

  1. 如果我们令 \(a = 0,b = 1,c = 2\) ,那么 \(S\) 串的所有字符之和在模 \(3\) 意义下与 \(T\) 相同。
  2. \(T\) 串存在两个相邻且相同的字符。

为什么呢?这里考虑归纳证明。即暴力模拟发现,当 \(n = 4\) 时,这一定成立。考虑当 \(n = k\) 成立时,如何证明 \(n = k + 1\) 也是成立的。

考虑将整个过程逆序,即每次操作对 \(T\) 串进行,每次可以将两个相同的字符变为未出现过的两个不同的字符。由于 \(T\) 串中存在两个相同的字符,因此一定可以将 \(T\) 串的后 \(n - 1\) 位任意转化成一个与 \(T\) 串有相同性质的串。因此 \(T\) 串的后 \(n - 1\) 位可以暂时先预留出一对相邻且相同的字符对,然后将 \(T\) 串的第一位利用相邻的那个字符对一点一点往前移,最后修改第一个字符使得 \(S\) 串第一个字符与 \(T\) 串相同。又由归纳假设,所以就得证了。

这个过程好像讲得不太清晰,我们用一个实例再来讲一下:

假如你的 \(S\) 串第一位为 \(a\)\(T\) 串第一位为 \(b\) 。那么我们可以把 \(T\) 串第二位到第四位先凑成 \(bcc\) 。由归纳假设,这总是可以达到的。并且我们预留了一对相同的字符。

这个证明似乎十分不严谨,但至少比官方题解啥也没说要好一点。

Bichrome Spanning Tree

题意

给定一张 \(n\) 个点,\(m\) 条边的图,你需要给这张图的边进行黑白染色。你的染色方案需要满足至少包含一条黑边和一条白边的最小生成树的权值和恰好为 \(X\) ,求染色方案数。

\(n \le 1000,m \le 2000\) 。其实 \(n,m\) 可以出到 \(10^5\)

技巧

寻找性质,kruskal算法的妙用。

题解

题解 其实官方题解已经讲得非常清楚了。首先随意求出一棵最小生成树,我们给那些没有在最小生成树上的边定义一个 $diff_i$ 的权值表示将这条边强制加入生成树之后,边权和的变化值。注意到一次黑白染色,最多强制让一条非树边加入生成树中,因此我们可以分情况一下。设 $Sum$ 为最小生成树的边权和。

  1. 如果 \(X - Sum < 0\) ,那么答案即为 \(0\)
  2. 如果 \(X - Sum = 0\) ,那么分两种情况计数:

    2.1. 如果最小生成树上的边颜色不全相同,那么生成树上的边有 \(2^{n-1} - 2\) 种方案,其余的边可以随意染色,共 \(2^{m-n+1}\)

    2.2. 如果最小生成树上的边颜色完全相同,那么生成树上有 \(2\) 中方案,非树边中只有 \(diff_i = 0\) 的边可以随意染色。
  3. 如果 \(X - Sum > 0\) ,那么生成树上的边必须完全相同,共 \(2\) 种方案,非树边中,\(diff_i < X - Sum\) 的边只能和生成树上的边完全相同;\(diff_i = X - Sum\) 的边可以任意染色,但至少有一条边与树边异色;其余边可以随意染色。

Dark Horse

题意

\(2^n\) 名选手,编号为 \(1\)\(2^n\) 。现在这 \(2^n\) 名选手将进行 \(n\) 轮淘汰赛,决出胜者。若 \(x < y\) ,则 \(x\) 能够战胜 \(y\) 。但有 \(m\) 个例外,\(1\) 号选手会输给这 \(m\) 个选手。问有多少中排列方式使得 \(1\) 号选手取得胜利。

\(n,m \le 16\)

技巧

利用容斥简化限制

题解

题解 之前的题解写的什么玩意儿……果然只口胡就扔一边不是个很好的习惯,以后还是尽量写一下。

为了方便,记这 \(m\) 个例外形成的集合为 \(A\) 集合。首先容易发现,\(1\) 号选手能够取得胜利,当且仅当

\[\{p_2\},\{p_3,p_4\},\cdots,\{2^{n - 1}+1,2^{n - 1} + 2,\cdots,2^n\} \]

\(n\) 个区间的最小值均不属于 \(A\) 集合。

考虑枚举一个集合 \(S\) 表示这个集合中的区间的最小值属于 \(A\) 集合,在此基础上进行容斥。于是接下来的核心就是计算,对于每一个集合 \(S\) 满足 \(S\) 中的区间最小值属于 \(A\) 集合的方案数。为了方便,这里不妨设 \(A_1 > A_2 > \cdots > A_n\) 。设 \(dp_{i,S}\) 表示当前考虑到 \(A_i\) 这个元素,当前满足最小值属于 \(A\) 集合的集合至少为 \(S\) 。这个 DP 会有以下两个转移。

  1. 当前元素不作为最小值出现在某个集合中,跳过这个元素。
  2. 当前元素作为最小值出现在某个集合中。你需要枚举这个集合的大小 \(k\) ,然后你需要任意找 \(k - 1\) 个比当前元素大的元素。由于我们保证了 \(A\) 集合是递减的,因此如果选择过程中意外选择了 \(A\) 集合中的元素,那么一定只会选择之前没有选择的元素。如何确定大于当前元素的个数呢?容易发现,之前确定的所有数一定都是大于这个元素的,因此这个数量也可以轻松确定。

容易发现这个 DP 只给集合 \(S\) 进行了排列,因此算完之后,还要对剩下的集合排列一下。最后答案要记得乘上 \(2^n\) ,即 \(1\) 号点随意排的方案数。

Two Faced Edges

题意

给定一张 \(n\) 个点,\(m\) 条边的有向图。问翻转每条边之后,整张图的强连通分量的数量是否改变。

\(n \le 10^3,m \le 2 \times 10^5,Time \ Limit = 5s\)

技巧

分析图论的一些结论与技巧

题解

题解 考虑翻转一条 $a$ 到 $b$ 的边,强连通分量的个数不会改变,当且仅当以下两个条件同时满足或同时不满足。

  1. \(b\) 可以到达 \(a\)
  2. \(a\) 可以不经过 \(a\)\(b\) 这条边,到达 \(b\)

这个性质可以自己证一证,四种情况仔细讨论一下,发现 \(a,b\) 两点的强连通分量一定会发生改变/不发生改变。

接着发现 \(O(nm)\) 的复杂度是可以接受的,因此可以考虑暴力一点求解。第一个条件直接从每个点 dfs 就行了,第二个条件怎么满足呢?

考虑仍然从每个点的每条出边 dfs ,记录一下从起点到每个点的经过次数。注意标记一下,如果从这条出边 dfs 的时候经过了这个点,需要及时退出。这样只要次数大于 \(1\) ,就一定存在两条出边不同的从 \(a\)\(b\) 的路径。其中一条肯定是 \(a\)\(b\) 的边,另一条就是不经过这条边到达 \(b\) 的路径了。注意当次数大于等于 \(2\) 的时候,也需要退出以保证复杂度的正确性。

然后……就被卡常了QAQ。你发现把边用 vector 存就会巨快无比……

Number of Digits

题意

\(f(x)\) 表示 \(x\) 在十进制下的位数。求所有满足 \(\displaystyle\sum_{i=l}^{r} f(i) = S\)\((l,r)\) 的对数。

\(S \le 10^8\)

技巧

小范围暴力以简化细节

题解

题解 容易发现这个东西小范围的时候情况比较奇特,所以不如直接将左端点位数 $\le 7$ 的情况跑暴力。

接下来考虑左端点位数 \(\ge 8\) 的情况。容易发现,如果位数 \(\ge 8\) ,区间长度就要 \(\le \frac{S}{8}\) 。因此可以考虑枚举区间长度 \(l\)。如果 \(l | S\) ,那么容易发现共有 \(10^{\frac{S}{l}} - 10^{\frac{S}{l} - 1} - l + 1\) 个合法区间。否则则一定恰好有 \(1\) 个合法区间。为什么呢?容易发现你可以构造出 \(l - S \bmod l\)\(\lfloor \frac{S}{t} \rfloor\) 位数,\(S \bmod l\)\(\lceil \frac{S}{t} \rceil\) 位数。由于小范围已经被判掉了,因此这么多个数总是存在的。

ColoringBalls

题意

给定一个长度为 \(k\) 的操作序列,每个位置只会有 r 或者 b 两种字符,分别表示将一个长度为 \(n\) 的全白序列的某一个子区间染红/蓝。你可以任意选择子区间,所选子区间亦可以是空区间。由于蓝色的颜料质量不大好,因此不能直接将白色染成蓝色,只能先染红,再染蓝。如果对于一个染蓝的操作,你所选的区间就不能包含一个白色的区间。问这样染色所能染出的不同的序列的个数。

\(n,k \le 70\)

技巧

对于小范围的题目,尝试压缩状态进行搜索。

题解

题解 首先可以将最后的序列,用 W 分成若干段。接着可以将相邻的相同的一段压成一个字符,这样每一段都会是一段 RB 相间的序列。考虑将这个序列的按照最小操作次数分类,这个最小操作次数是多少呢?

打表之后,可以发现这样的规律:

操作 \(1\) 次:R

操作 \(2\) 次:B,RB,BR,RBR

操作 \(3\) 次:BRB,RBRB,BRBR,RBRBR

还可以发现,对于最小操作次数为 \(1\) 的序列,操作序列必定为 r ,次数为 \(2\) 的操作序列为 rb ,次数为 \(3\) 次及以上的序列只需要满足前两位为 rb ,后面若干位任意排列均可。

最后再将这个形成的序列排序。发现将状态这样压缩之后,不同的状态数只有大约 \(4 \times 10^5\) 左右。于是我们可以暴力搜索出所有的状态,对于每个状态,每次单独计算方案数。接下来的问题就是,如何判断方案是否合法?

我们可以将序列从大到小排序,依次贪心选择。先对于每个数从大到小依次确定其第一个 r 与 b 的位置。随后再对于每个数,找到任意一个未被选择的长度为剩与长度的子操作序列即可。

判断合法之后,方案数的计算也有不少细节。首先注意操作次数相同的序列,不同排列不能重复计算,因此需要乘上的是可重排列方案数;头尾的 W 不一定需要存在,但序列中间的 W 是一定要存在的;通过操作次数反推合法序列的时候,注意头尾的 R 不一定存在。最后将所有一定存在的区间的预留至少一个位置,剩下的用隔板法即可计算。

这玩意儿真心难写……看了一下别人的写法才写的……

Christmas Tree

题意

你有一种两个联通块合并的方式,这个方式即为,从每个联通块中各选出一个点,然后将这两个点合并为一个点,即将所有连向这两个点的边连向这个新点,并将原来的两个点以及那些边删去。问你需要通过这样的方式,将 \(A\) 条长度不超过 \(B\) 的链合并成一棵给定的树。在满足 \(A\) 最小的情况下,最小的 \(A,B\) 的值。

\(n \le 10^5\)

题解

题解 这题似乎并不难?只是有点细节……

容易把题意转化为,用 \(A\) 条长度不超过 \(B\) 的链将整棵树覆盖。第一问的答案显然可以直接贪心解决。第二问容易想到二分答案,二分答案之后需要计算出,至少需要多少条长度不超过一个定值的链能够合并成。考虑链合并的地方,首先需要让链合并尽量多条,其次需要让留下来继续向上的链长度尽量短。这里我不大会贪心,于是就写了个很暴力的做法……就是再二分一个答案,二分这个留下来的链的长度。然后再在这个上面 two pointers 扫一遍得到答案。复杂度来到 \(O(n\log^2n)\)

Prefix-free Game

题意

给定一个字符串集合 \(S\) 。定义一个字符串集合是合法的,当且仅当不存在一个串是另一个串的前缀。接下来 Alice 和 Bob 轮流往这个集合中加入一个长度不超过 \(L\) 的新串,要求加入新串之后这个集合仍然是合法的。不能操作的一方将输掉比赛。问谁能取得胜利。

\(n,\sum|s_i| \le 10^5\)

技巧

对于博弈问题,尝试打表寻找 SG 函数的规律。

题解

题解 首先可以把所有串插到 01Trie 上。如果我们定义,选择了一个节点,就选择了其子树。容易发现,你选择的字符串在 Trie 上不能有任意一个地方被选择。如果 Trie 上的所有节点都被选择,那么就不能再进行操作了。一个人的操作等价于将深度为 $i$ 的点减少一个,将深度为 $i + 1,\cdots,j$ 的节点数增加一个。打表找规律发现,一个深度为 $i$ 的节点的 SG 函数值为 lowbit(L - i + 1) 。于是只要将所有串插到 Trie 上。然后判断每个空区间即可。

Squirrel Migration

题意

给定一棵 \(n\) 个点的树。定义一个排列 \(P\) 的价值为 \(\displaystyle\sum_{i=1}^n dis(i,p_i)\) 。其中 \(dis(i,j)\) 表示 \(i\)\(j\) 在树上的距离。求满足权值最大的排列的方案数。

\(n \le 5 \times 10^3\)

技巧

对于某些满足最值的计数问题,可以考虑给它估一个比较紧的界,然后再来证明这个界是可达的,并进行计数。

题解

题解 考虑每条边对答案的贡献。容易发现每条边的贡献,最多就是两边子树大小的较小值的两倍。如何构造使得这个最大值可达呢?考虑分为以下两种情况。

  1. 重心有两个点

    这样这两个节点一定相连,且子树大小相同。容易发现,只需要一个重心的子树里的点,路径另一端一定在另一个子树内,可以发现这样一定到了上界。在这种情况下,方案数即为 \(((\frac{n}{2})!)^2\)

  2. 重心仅有一个点

    容易发现,以重心为根,只要每个重心的儿子的子树内的节点,路径另一端不在该子树内即可。这个东西不大好计数,于是考虑容斥。即对于每个 \(i\) ,计算有 \(i\) 个节点不满足条件的方案数。这个东西可以用 DP 来解决。设 \(dp_{i,j}\) 表示当前考虑到第 \(i\) 个子树,不满足条件的点数至少有 \(j\) 个,这 \(j\) 个点的方案数。于是我们会有

\[dp_{i,j} = \sum dp_{i - 1,j - k} \binom{sz_i}{k} A(sz_i,k) \]

最后的答案即为 \(\displaystyle\sum (-1)^i dp_{tot,i} (n-i)!\)

MUL

题意

给定一个长度为 \(n\) 的数列 \(a_i\) 。你每次可以选择一个数,将这个数及其倍数删去。你需要最大化留下来的数的权值和。求这个权值和。

\(n \le 100\)

技巧

对于一类限制不好处理的最优化问题,考虑网络流/最小割模型。

题解

题解 考虑题目的要求,大概就是,如果对于一对 $i,j$ 满足 $i$ 被删除,那么 $j$ 就一定会被删除。如果 $i$ 是一个负数,$j$ 是一个正数。那么要么选择删掉 $j$ 的正数贡献,要么选择保留 $i$ 的负数贡献。因此可以将 $i$ 向 $j$ 连一条流量为 $\infty$ 的边。原点向所有负数连一条 $-a_i$ 的边,正数向汇点连一条 $a_i$ 的边。然后直接跑最小割即可。

本来是个还不错的题……可惜范围小了……暴力直接跑过去了QAQ。

XorShift

题意

给定一个 \(n\) 个数集合。每次你可以将一个数翻一倍,加入这个集合中;或者选择两个数,将这两个数的异或值加入这个集合中。注意每次操作之后,原来的数字会得到保留。问这个集合最后会有多少个 \(\le X\) 的数。

\(n \le 6,a_i,X \le 2^{4000}\)

题解

题解 考虑集合里的数的形成过程,容易发现最终集合里的数,一定可以用这 $6$ 个数乘上 $2$ 的若干次方的异或和来表示。我们把每一个二进制数看成一个多项式,那么异或操作相当于将两个多项式在模 $2$ 意义下相加,翻倍操作相当于将这个多项式乘上一个 $x$ 。容易想到,这个集合内的所有元素,一定可以由一个次数最低的多项式通过这两种操作构成,因此我们需要找到这个最小的多项式。这个多项式即为所有给定多项式的最大公约数。求最大公约数的过程只需要类似进行辗转相除即可。

得到了这个最大公约数,考虑如何求小于等于 \(X\) 的多项式的个数。设这个最大公约数的次数为 \(DegGcd\)\(X\) 的次数为 \(DegX\) 。当我们确定了前 \(DegX - DegGcd\) 位之后,最后的若干位是唯一确定的。因此只需要特判一下前 \(DegX - DegGcd\) 位与 \(X\) 相同的情况,看一下这么确定的后面的位是否满足条件即可。

Collecting Balls

题意

在一个平面内共有 \(2n\) 个球,保证这 \(2n\) 个球均在第一象限,给定每个球的坐标。此外坐标轴上共有 \(2n\) 个机器人。每个机器人的位于 \((1,0),(2,0),\cdots,(n,0),(0,1),(0,2),\cdots,(0,n)\) 。每个机器人会沿着垂直于坐标轴的方向行走,直到遇到一个球,就会将这个球拿走,机器人也会消失。如果没有遇到球,机器人也会消失。问有多少种不同的机器人收集球的顺序,满足所有球都被收集。

\(n \le 10^5\)

技巧

模型的转化,经典模型的运用

题解

题解 考虑每个球会被哪个机器人收集,这样就可以建出一个二分图。由于一个球恰好只有两条出边,所以可以类似于原来讲过的某题的思路,将这两个机器人之间连一条边,每条边只能被它相连的两个点选择。容易发现,如果最后是有解的,那么这张新图一定是一个基环树森林。回到原题,原题除了需要确定每个球被谁拿走之外,还需要求满足条件的排列个数。对于某个点而言,与这个点相连的某一条边可以被这个点选择,当且仅当与这个点相连的所有未选择的点,权值均大于这个被选择的点。

考虑树边,容易发现树边被哪个点选择一定是确定的,于是只需考虑顺序问题,由于每个子树内的相对顺序不能改变,而这个点往上的父亲的边在最后排列中的顺序是唯一确定的,因此只需要一个可重排列。

考虑环上的边,容易发现,我们只需要给定一个顺逆时针的顺序,那么每条边被哪个点选择也是确定的。接下来考虑顺序问题。我们把这个环从点权小于左右两边的点处断开,这样一个环就可以断成若干棵树,类似于树上的做法即可。需要注意挂在环上的子树的方案。

是个细节题……不想写了……

Flip and Rectangles

题意

给定一个 \(n \times m\) 的矩阵,每个位置有黑白两种颜色之一。每次你可以翻转某一行或某一列的颜色。问经过任意次操作之后,最大的全黑矩形面积最大为多少。

\(n,m \le 2000\)

技巧

利用归纳法,转化为经典模型。

题解

题解 首先给出结论。我们定义一个 $2 \times 2$ 的子矩阵是不好的,当且仅当这个子矩阵包含了奇数个黑格。可以证明如果一个子矩阵没有包含不好的子矩阵,那么你一定可以将这个子矩阵变为全黑。右推左是比较好证的。因为一无论你如何操作,你是无法改变某个 $2 \times 2$ 的子矩阵的黑格奇偶性的。考虑如何证明右推左。

利用归纳法容易发现,由于任意操作不会破坏这个子矩阵为全好的性质。因此可以任意操作使得第一行与第一列变为全黑,这样我们又可以推出第二行与第二列也为全黑,以此类推即可得证。

接下来问题就可以转化为一个经典模型,即统计最大的全黑子矩阵。

然而……这个东西我没想出来……大概做法是,枚举每个点,然后往上扩展到极限,随后往左右扩展得到一个极大的子矩形,可以发现这样做可以统计到所有的极大子矩形。往左右扩展的过程可以用左右两个单调栈实现。

Young Maids

题意

给定一个排列 \(p_i\) ,你可以从中选择两个相邻的数,不破坏其相对顺序,放到 \(q\) 数组的最前面。你需要最小化 \(q\) 的字典序。

\(n \le 2 \times 10^5\)

技巧

数据结构的小技巧

题解

题解 这种题都不会做了……真的有点菜啊……

首先不难发现,每次操作会将整个序列断成三段;每次操作等价于在某一段的奇数位上选择一个数,偶数位且同一段上选择一位数,从后面加入 \(q\) 数组。字典序可以考虑直接贪心,这样我们就可以得到一个 \(O(n^2)\) 的做法。考虑如何优化这个做法。

由于每次操作会将整个序列断成三段,因此每次新形成一段,就将这个子序列且位于奇数位置上的最小值加入一个堆。然后每次从堆中取出最小值,然后用 RMQ 查询一下偶数位上的最小值即可。

Prime Flip

题意

给定一个长度无穷的数列,其中有 \(n\) 个位置为 \(1\),其余位置均为 \(0\)。每次可以选择一个长度为奇质数的区间,翻转这个区间的数字。问最少要操作多少次将这个序列变为全 \(0\)

\(n \le 100,a_i \le 10^7\)

技巧

哥德巴赫猜想,差分简化模型

题解

题解 首先可以将原序列差分一下,这样每次操作即可转化为,选择两个距离为奇质数的点,翻转这两个点的颜色。由哥德巴赫猜想,我们可以得到:

  1. 翻转两个距离为奇质数的点,需要 \(1\) 次操作;
  2. 翻转两个距离为奇合数的点,需要 \(3\) 次操作;
  3. 翻转两个距离为偶数的点,需要 \(2\) 次操作;

于是,我们会得到这样一个策略:

首先尽可能的多匹配两个奇质数点,然后将距离偶数的点全匹配掉。如果最后还剩了两个奇偶不同的点,还需要多花 \(3\) 次操作。所以只要做一个二分图匹配就可以了。

SS

题意

定义一个串为偶串,当且仅当这个串长度为偶数,且前后两半完全相同。对于一个给定的字符串 \(S\),定义一个函数 \(f(S)\) 表示将字符串 \(S\) 后添加一个非空字符串 \(T\),满足新串是一个偶串,且 \(|T|\) 尽可能小。求 \(f^{(\infty)}(S)\)\(l\) 个字符到第 \(r\) 个字符,每种字母的出现次数。\(f^{(n)}(x)\) 表示将函数 \(f(x)\) 迭代 \(n\) 次。

\(l,r \le 10^{18},|S| \le 2 \times 10^5\)\(S\) 为一个偶串。

技巧

border的相关性质。

题解

题解 由于原串一定为一个偶串,我们设原串为 $SS$ 。不妨设 $S$ 的最短循环节为 $T$ ,那么可以得到 $f(SS) = STST$。继续迭代下去,我们就需要知道串 $ST$ 的最短循环节。所以我们不妨设一个函数 $g(S) = ST$ 。$T$ 串的定义与上文相同。我们只需要探究一下 $g$ 函数的性质即可。

如果 \(|T|\)\(|S|\) 的约数,不难发现 \(g(ST) = STT\)

如果 \(|T|\) 不是 \(|S|\) 的约数,会有 \(g(ST) = STS\)

以此类推,我们可以发现,对于第二种情况,有 \(g^{(n)}(S) = g^{(n - 1)}(S) + g^{(n - 2)}(S)\) 。而对于第一种情况,当 \(g\) 函数被迭代无穷次之后,形式与这个式子是相同的,因此两类可以一起考虑。而 \(f^{(n)}(SS) = g^{(n)}(S) + g^{(n)}(S)\) ,所以我们可以直接得到 \(f\) 的递推式。注意到这样增长次数是 \(\log\) 级别的,所以可以一步步模拟字符的个数。

考虑如何证明第二种情况的式子。设 \(S = n \times T + T'\) ,不妨设存在一个更小的循环节 \(x\)

如果 \(x\) 不是 \(|T|\) 的倍数,那么一定存在一个长度为 \(\gcd(x,|T|)\) 的循环节,与 \(S\) 串的循环节为 \(T\) 矛盾。

否则仔细讨论一波大概也能得到矛盾……已经想不清了……算了……

相关文章: