atcoder题目选做
AGC054E ZIG ZAG Break
好强的东西
我们这么去考虑啊
首先不妨假设 \(a_1<a_n\),那么应该有一个结论,就是有:
\(\{p_i\}\) 合法当且仅当存在一个 \(i\),满足 \(a_i\le a_1\) 且 \(a_n\le a_{i+1}\)
那么,我们考虑先证明充分性:
考虑倒着这个过程,最后只剩下 \(p_1\) 和 \(p_n\),然后每次考虑添加去的位置是 \(pos\),这个假如破坏了原本的一个 \(i\),那么不好意思,根据 \(x\) 的大小讨论, \(pos\) 或者 \(pos+1\) 依然是合法的。
必要性的话,考虑每次考虑随便删除这个序列的一个峰,然后最后只剩下 \(i\) 这个峰,考虑处理成 \(p_1,p_i,p_n\) 这类的数列就可。
那么我们就证明了上面结论的充要性。
那么,不妨设 \(p_n=p_1+k\),我们考虑把数分为三类,就是说 \([1,p_1)\) 和 \((p_1,p_1+k)\) 和 \((p_1+k,n)\)
那么于是有这样子我们的排列数就是:
整理就是
进一步的,我们枚举一下
考虑拆一下,且令 \(k=k-2\)
换成组合数
这玩意考虑一下,就是说
我们再考虑 \(a_1>a_n\) 的情况,那就是必定有
\(\{p_i\}\) 合法当且仅当存在一个 \(i\),满足 \(a_i\ge a_1\) 且 \(a_n\ge a_{i+1}\)
我们也如此考虑,那么应该是
这两个加一块用 \((n-1)!\) 减去就是答案。
ARC128D NeqNeq
题意
给你一个序列,随便的 \(\{A_i\}\)
然后你每次可以做一个操作,就是把连续的三个数字 \(x,y,z\) 如果 \(x\not = z\),那么就可以删去 \(y\),然后你可以收手不打了。
问最后可能有多少种不同的序列。
题解
我们考虑观察如果有两个连续位置满足 \(a_i=a_{i+1}\) 那么,考虑分段。
然后考虑怎么去搞一段的就可以了。
我们发现,设 \(f_i\) 是以 \(i\) 结尾的,如果 \(i,j\) 之间有超过三种颜色那么随便删,直接转移就好了,否则的话,就不能去掉,那么就用 \(pre_i\) 表示能转移的(有三个颜色的)最靠后的位置。那么转移方程就是
然后把每段乘起来就是答案了。
ARC127D Sum of Min of Xor
题意
给定你两个什么序列,然后计算什么
这玩意好难啊
题解
我们考虑分治,就比如说我们令 \(C_i = A_i \oplus B_i\),那么对于一个 \(C_i = C_j\) 的对,我们发现,随便选一个 \(A_i\oplus A_j\) 即可,那么每次只要能查询一个数对于之前一堆数字的异或和就可以,这玩意可以通过简单的前缀和计算。可以使用数组,或者是 map<int, vector<int>>
否则的话,我们比如最开始分两个集合 \(S,T\) 表示 \(C_i\) 这最高位是 \(0/1\) 的集合,然后考虑每次计算 \(i\in S,j\in T\) 的对 \((i,j)\),因为这个位上 \(A_i \oplus A_j\) 和 \(B_j \oplus B_i\) 不一样。
那么我们可以通过 \(A_i\) 给 \(S\) 分类为 这一位 \(A_i\) 为零的为 \(S_0\) 否则为 \(S_1\),那么同理有 \(T_1\) 和 \(T_0\),我们对于一个 \(S_x,T_y\) 如果 \(x=y\),那么应该选 \(A_i\oplus A_j\) ,否则应该选 \(B_i \oplus B_j\)。然后可以对于 \(S\) 和 \(T\) 分别递归下去。
那么现在的问题相当于是给你一个集合 \(S\),再给一个集合 \(T\) ,求出来
那么我们考虑对于每个位分开讨论,只要用 \(cnt_i\) 表示 \(T\) 中有多少个数字 \(i\) 位是 \(1\),那么就有
然后就解决了。
ARC127E
题意
给你一个 \(n+m\) 长度的操作序列,然后依次执行,维护一个优先队列 \(s\),每次
- 弹出 \(s\) 中的最大值
- 往 \(s\) 中加一个数字
要求只能添加一个排列
题解
我们考虑随便整一个贪心,就是第 \(i\) 次添加 \(i\),那么应该有这是的集合是最优秀的。
我们令一个随便整一个集合,那么必然有 \(x_i\le z_i\),其中 \(x_i\) 表示你选的这个集合里第 \(i\) 大的数字,而 \(z_i\) 同理,表示最优秀集合的。
然后考虑直接可以 \(dp\) 出来 \(x\) 集合的数量,这样子的 \(x\) 也显然可以取出来。
ARC125D
题意
给定长度为 \(n\) 的数组,求有多少个子序列只出现过一次。
题解
容易想到 \(dp\),令 \(dp_i\) 表示 \(1\sim i\) 中以 \(a_i\) 为结尾的满足条件的子序列的个数,观察性质,当相同的数再次出现时,前一个数能构成的所有子序列都会重复,因此这里要减去贡献,显然减法的操作只会在这种情况产生。考虑到 \(i\) 时哪些是合法的转移,显然就是上一次出现的位置到当前位置的所有子序列都可以接上 \(a_i\),之前的不合法。
ARC125E Snack
题意
你有 \(n\) 个零食, \(m\) 个人,然后有 \(a_i,b_i,c_i\) ,就是
- \(a_i\) 表示第 \(i\) 种零食最多有 \(a_i\) 个
- \(b_i\) 表示第 \(i\) 个人,对于每种零食最多取 \(b_i\) 个
- \(c_i\) 表示第 \(i\) 个人,最多拿多少个零食
求最多一共能拿多少个零食
题解
考虑直接网络流,源点 \(S\) 与每个零食连一条流量为 \(a_i\) 的边,第 \(i\) 个零食向第 \(j\) 个人连 \(b_j\) 的边,每个人向汇点 \(T\) 连 \(c_j\) 的边,那么最大流就是答案。
直接跑肯定 gg,我们考虑怎么去优化他,考虑模拟啊。考虑最小割等于最大流,那么我们只需要求最小割。
我们考虑对于零食割掉了 \(cnt\) 条边,那么肯定是 \(a_i\) 最小的 \(cnt\) 的零食。因为其他的方面都是对称的。
我们在考虑对于其他的那些零食,他的贡献就是 \(\min(c_i,(n-cnt)\times b_i)\)
我们考虑怎么快速求出上面那个东西,怎么整啊考虑对于人以 \(\frac{c_i}{b_i}\) 进行排序,那么用一个指针进行维护即可。
那么这样子就搞完了。
ARC125F Tree Degree Subset Sum
题意
给你一棵树,然后问你,有多少个 \((x,y)\) ,满足你能选出来 \(x\) 个点,然后他们的度数和为 \(y\)。
题解
首先就是,这个傻逼树的条件就是nt,因为一个无根树对应着一个 prufer 序列,只需要满足 \(\sum d_i=2 n - 2\) 即可。
那么题就转化为了 给你一个和为 \(2n-2\) 的序列,然后 \((x,y)\) 的个数,我们考虑对于所有数字减一(这是毫无影响的),那么就是给一个和为 \(n-2\) 的序列,然后 \((x,y)\) 的个数。
我们考虑对于一个 \(y\),用最少的的元素凑出来就是 \(L(y)\),同理有 \(R(y)\),那么我们有 对于所有的 \(L(y)\le x \le R(y)\),这些 \(x\) 都是合法的。
我们考虑怎么去证明这个东西,假设有 \(z\) 个 \(v_i=d_i-1\) 是 \(0\),那么我们只需要证明
对于一个任意选择的方案,其权值和为 \(k\),其选区的个数为 \(c\),那么有
因为 \(k-c=\sum_{i\in S}(v_i-1)\),现在最小值就是所有 \(0\) 的个数,即 \(-z\),那么我们在考虑所有 \(k-c\) 中的数字都是大于 \(1\) 的情况。
那么 \(k-L(k)\) 和 \(k-R(k)\) 均在 \([-z,z-2]\) 之间,那么就有他俩相差不超过 \(2z-1\) ,所以就证明完了。
然后,那么直接考虑做一个背包,就是说,我们只要算出来对于每个值我们最多用多少个最少用多少个就行,这玩意显然可以用 \(dp\) 解决。
就是一个 \(dp_i=\min | \max(dp_{i-sv}+s)\),由于最多有 \(O(\sqrt n)\) 个不同的数字,那么有 复杂度为 \(O(n\sqrt n)\)
ARC124D Yet Another Sorting Problem
题意
给你一个 \(1\sim n + m\) 的排列,然后你每次可以选一个 \(1\le x \le n\) 和 \(n+1\le y \le n+m\),交换 \(p_{x}\) 和 \(p_{y}\)
题解
我们考虑用群论的思想解题,这玩意就是个置换环。我们考虑 \(i\rightarrow p_i\) 变成原本的图,然后那么原本图就是很多个环构成,我们的目的是操作这个图让每个环都是自环。
我们考虑让 \([1,n]\) 的点为白色, \([n+1,n+m]\) 的点为黑色。
那么我们每次的操作 \((x,y)\) 就是选择一个黑色点,一个白色点。
然后让 \(x\rightarrow p_y\) 且 \(y\rightarrow p_x\),那么就有,我们直接这么考虑就可以了,对于一个异色环,我们明显可以在 \(\text{sz}-1\) 的操作次数下拆成每个自环。
然后考虑有 \(A\) 个白色大于一的同色环,然后 \(B\) 个黑色大于一的同色环,很明显是先两两配对,然后多的和异色环配对。
那么我们就推一下答案应该是 \(\max(A,B)+n+m-num\) 其中 \(num\) 是最后环的个数
这个玩意应该是 \(num=(cnt-A-B)-\max(A,B)+\min(A,B)\) 其中 \(cnt\) 是原来的环的个数
整理得到答案是 \(n+m-cnt+2\max(A,B)\)。
ARC124E Pass to Next
题意
\(n\) 个人排成一个环,第 \(i\) 个人有 \(a_i\) 个球,可以同时给下一个人 \(x(0\le x\le a_i)\) 个球,求每个人最后会有球 \(b_i\) 个,问所有不同的 \(b\) 序列的 \(\prod\)
就是这玩意。
题解
我们首先考虑一下,什么样的传球方法能不漏唯一的对应一个 \(b\) 序列。然后我们发现,只有当每个人传球数量 \(\min{x_i}=0\) 的时候,这样的一个传球序列表示一个最后的 \(b_i\) 序列,否则我们可以每个人都少传一个球。
我们考虑最后这个式子的组合意义其实是什么?
就是最后出来一个 \(b\) 序列之后每个人从自己手里拿一个球的方案数。对此,我们可以直接分类讨论用动态规划解决即可。
我们令 \(f_i\) 表示第 \(i\) 个人选的是自己原本的球,前 \(i-1\) 个人选择的方案数,而 \(g_i\) 表示第 \(i\) 个人选的是上一个人送她的球。
我们设 \(s_i(n)=\sum_{j=1}^n j^i\),那么有
由于这个人可能会给后边的人 这样的方案数就有 \(s_1{(a_i)}f_i\)
由于这个第 \(i\) 个人的选择已经确定,但是不确定怎么传,所以 \(g_i(a_i+1)\)
那么就是 \(f_{i+1}=s_1{(a_i)}\times f_i+g_i\times (a_i+1)\)
然后考虑 \(g_i\) 的转移,我们发现应该就是
这个转移需要计算 \(i\) 和 \(i+1\) 的选球方案,考虑给了第 \(i+1\) 个人 \(b\) 个,那么就是 \(f_i\times \sum_{b=1}b\times (a_i-b)\),就是 \(f_i\times (s_1(a_i)\times a_i-s_2(a_i))\) 。
那么这个也是显然的就是 \(g_i\times s_1(a_i)\)
那么 \(g_{i+1}=g_i \times s_1(a_i)+f_i\times (s_1(a_i)\times a_i-s_2(a_i))\)
由于转移是一个环,所以刚开始的时候要钦定 \(f_1=1\) 或者是 \(g_1=1\) ,这两种情况的答案分别是 \(f_{n+1}\) 或者是 \(g_{n+1}\) 对吧。
然后我们还需要容斥,就是加上一个 \(\min x_i=0\) 的条件,很简单,我们只需要做两次 \(dp\),强制让第二次的 \(dp\) 转移最小是从 \(1\) 开始即可。两次答案相减即可。
ARC124D F - Chance Meeting
题意
在 \((1,1)\) 处有个肉三鲜,在 \((n,1)\) 处有个三月底,你每次可以让肉三鲜向右或者下移动一个,或者让三月底向右或者上移动一个,问有多少种不同的操作序列,可以使得肉三线和三月底恰好碰撞一次(在一个格子里)。
题解
我们考虑如果肉三鲜和三月底在一个行里才能相遇,于是我们设 \(f(i)\) 表示他们可以在某一行的第 \(i+1\) 个格子里唯一一次相遇的方案数量,那么答案就是
这玩意相当于一个对称。
那么我们再考虑怎么求出来 \(f\)
这玩意不会啊。于是考虑容斥。
然后自然就有,考虑如果不是第一次相遇,那么就有上一次相遇,自然就是通过枚举上一次相遇的点来容斥,容斥系数是2乘上一个卡特兰数,这很好理解
其中 \(h_i=\frac{\binom{2i}{i}}{i+1}\)
然后就是个卷积!
ARC122D XOR GAME
题意
给定一个长度为 \(2n\) 的序列,Alice 和 Bob 执行以下操作 \(n\) 次:
- Alice 选择一个之前未被选择过的数字 \(x\)。
- Bob 选择一个之前未被选择过的数字 \(y\)。
- 这一轮的价值为 \(x \oplus y\)。
\(n\) 轮后总价值为每一轮价值的最大值。Alice 想最大化总价值,Bob 想最小化总价值。在两人都选择最优策略的情况下,求最后总价值是多少。
题解
首先,题目的意思是,从长度为 \(2n\) 序列中匹配 \(n\) 对数,并将匹配的两个数异或,使得的异或值最大值最小。
那么,我们就考虑讨论现在这些数字的最高位,如果有偶数个 \(0\) 和偶数个 \(1\),那么肯定是 \(0\) 的匹配在一起,\(1\) 的匹配在一起,分割成了两个子问题。
否则,肯定有奇数个 \(1\) 和奇数个 \(0\),那么就是说,肯定有一个 \(1\) 和 \(0\) 匹配起来,这个问题可以简单的使用 \(\text{Trie}\) 解决。
ARC122E Increasing LCMs
题意
给你一个序列 \(\{a_i\}\),然后让你重排 \(a\),使得 \(y_i=\text{lcm}_{j\le i}a_j\),这玩意递增。求一个方案数。
题解
我们考虑,倒序向前排,那么就有,我们在一个 \(i\) 位置可以填 \(a_i\),当且仅当
那么就可以填,变换一下就是
这玩意你考虑指数形式显然成立对吧。
然后为啥要倒序做,我们考虑这玩意就是说一个数可以填 \(j\) 位置,那么他肯定可以填 \(i<j\) 的 \(i\) 位置。
ARC122F Domination
题意
你有 \(n\) 个红石头,第 \(i\) 个红石头的坐标为 \((rx_i,ry_i)\),你有 \(m\) 个蓝石头,第 \(i\) 个蓝石头的坐标为 \((bx_i,by_i)\) 。你可以移动蓝石头到 \((x,y)\),那么移动的花费就是 \((x,y)\) 到 \((bx_i,by_i)\) 的曼哈顿距离。
问你用最少的花费使得每个红色石头的右上方至少有 \(K\) 个蓝色石头。问你最少花费。
题解
我们首先考虑这个 \(k=1\) 的情况如何解决。
我们考虑一个 \(O(n^2)\) 的 dp 来解决这个问题。
首先我们发现,如果一个红石头在另外一个红石头的左下方,那么这个红石头一定不需要考虑,于是我们只需要删去前者,即可,那么剩下的一堆红石头我们按照 \(x\) 从小到大排序,其中 \(y\) 坐标从大到小。
那么我们列出 \(dp\) 方程,其中 \(f_i\) 表示前 \(i\) 个红色石头都满足条件的最小代价。那么我们枚举上一段被覆盖的区间右端点,那么就是
关于这个 \(dp\),我们考虑下边这个有向图来描述。
把一个石头拆成两个点,分成 \(x\) 坐标和 \(y\) 坐标,将所有的 \(x\) 坐标和从小到大排序,所有的 \(y\) 坐标从大到小排序,每个节点向下一个连权值差的边,下一个向上一个连 \(0\) 的边,所有蓝石头的 \(y\) 坐标的石头向 \(x\) 石头的边。那么这个图上
第 \(i\) 个红色石头的 \(y\) 石头到 \(j\) 个红色石头的 \(x\) 石头的最短路就是
然后在加上转移,就是 \(i\) 个红色的 \(x\) 石头向 \(i+1\) 个红色的 \(y\) 石头连 \(0\) 的边。
那么这样子 \(1\) 号红色石头的 \(y\) 石头到 \(n\) 个红色石头的 \(x\) 坐标的最短路就是答案。我们考虑跑一个流量为 \(K\) 的费用流就是答案了。
跑 \(EK\) 的时间复杂度是 \(O(Kn^2)\) ,我们考虑怎么跑到 \(O(Kn\log n)\) 。
我们考虑 \(\text{dijkstra}\) 求费用流,就是给每个点加势能 \(h_i\),对于一个原来的边 \((x,y,c)\),每个新的边就是 \(w+h_x-h_y\),保证这玩意 \(\ge 0\) 即可。令每次的势能增加量为 \(d_i\) 即可。
证明:
- 考虑每个原来流量非 \(0\) 的边,那么有 \(d_y\le d_x+(w+h_x-h_y)\) 化简就有 \(w+h_x'-h_y'\ge 0\)
- 对于每个流量为 \(0\) 而之后流量非 \(0\) 的边,那么应该有 \((y,x)\) 是最短路 \(d_y+w+h_y-h_x=d_x\) 那么化简之后就是 \(-w+h_x'-h_y'=0\) 即 \((x,y)\) 这条边的权值为 \(0\)。
ARC121D 1 or 2
题意
你有 \(n\) 个糖果,第 \(i\) 个糖果的美味度是,每次可以选择吃 \(1\) 个或者 \(2\) 个,最后要全部吃完,每次把吃完的糖果的美味度和写到黑板上,然后令最大值为 \(X\),最小值为 \(Y\) ,你需要最小化 \(X-Y\) 的值。
题解
我们考虑假定每次必须选两个糖果的话,那么我们需要添加一些为 \(0\) 的糖果,然后单独选的糖果配对就是 \(0\) 的糖果,我们考虑这个问题如何解决。
那么显然就是说,糖果按照美味度排序的话,最大的糖果配最小的,次大的糖果配次小的,以此类推。
这个证明很简单,我们设 \(A\le B \le C \le D\) ,那么显然有 \(\min(A+D,B+C)\ge \min(A + C,B+D)\) 且 \(\max(A+D,B+C)\le \max(A + C, B + D)\) 是吧。
然后我们每次向里边添加两个零,然后暴力做就完了。
时间复杂度为 \(O(N^2)\)
ARC121E Directed Tree
题意
你有一棵树,然后有一个排列 \(a_i\),对于每个 \(i\),要满足从 \(a_i\) 不能是 \(i\) 的祖先。问 \({a_i}\) 的方案数,对于 \(998244353\) 取模。
题解
我们首先考虑问题转化,那么我们就将问题转化为,对于一个节点 \(i\),\(a_i\) 不能填她子孙节点的情况。
我们考虑设 \(S(i)\) 表示钦定 \(i\) 个位置不合法的方案数量,那么我们就有
那么考虑怎么求出来 \(S(i)\),我们设 \(f_{i,j}\) 表示 \(i\) 子树内,钦定了 \(j\) 个节点不合法的方案数量。
那么我们的 \(dp\) 方程就是
那么初始就是 \(dp_{i,0}=1\),我们再考虑最后要看看这个节点合不合法,那么就是 \(dp_{i,j}=dp_{i,j}+dp_{i,j-1}\times (\text{sz}(i) - j)\)
这个转移方程看似是 \(O(N^3)\) 的,但是考虑每个点两两配对的思想的话,她其实是 \(O(N^2)\) 的。
ARC121F Logical Operations on Tree
题意
给你一个点权分别是 \(0/1\) ,边权分别是 \(\and\) 或者是 \(\or\) 的树,每次你可以执行去掉一条边,然后用一个权值为位运算结果的点代替这个边两边的点。
问有多少种合法的树,能够删成一个为 \(1\) 的节点。
题解
我们讨论一下啊,对于一个度数为 \(1\) 的节点
- \(\or 1\) :那么肯定行
- \(\and 1\) :这是废话,直接干
- \(\or 0\):这是废话,直接干
- \(\and 0\):现在算肯定比之后算要好,因为影响范围小了。
所以直接就是每次找一个度数为一的节点直接做就是最好的。
那么我们可以考虑 \(dp\) 解决这个问题。令 \(f_{i,0/1/2}\),表示 \(i\) 节点子树,这个点权值是 \(0/1\) 且没有 \(\or 1\) 的方案数和有 \(\or 1\) 的方案数。那么 dp 方程就是:
初始是 \(f_{k,0}=f_{k,1}=1\),答案就是 \(f_{1,1}+f_{1,2}\)
ARC120D
题意
给你一个长度为 \(2n\) 的序列 \(A\),再叫你构造一个合法的长度为 \(2n\) 的括号序列,对于每对匹配的括号 \((i,j)\),权值为 \(|A_i-A_j|\),一个括号序列的权值是他所有匹配括号对的权值和。
问权值最大的合法括号序列是什么。
题解
我们考虑,直接按照 \(A\) 进行排序,然后强制让前一半的 \(A\) 和后一半的 \(A\) 做匹配。匹配的方式是,我们栈内只存同一类型的 \(A\),保证他们不匹配,然后遇到一个不一样的就弹出就行了,为空的时候直接压栈就好了。