Loading

CodeForces 比赛记录

带星号的表示 vp。

\(*\) CF Round 601 Div.1

做出 A 和 B1。

B2. Send Boxes to Alice (Hard Version)

考虑 \(a\)前缀和数列 \(S\),在 \(a\) 中移动一个数,相当于在 \(S\) 中单点 \(\pm 1\)。并且 \(S_n\) 一定是不变的,且最终的公约数一定是 \(S_n\) 的约数。显然只需要枚举所有质数 \(p\mid S_n\)。并且“所有 \(S_i\) 都是 \(p\) 的倍数”与“所有 \(a_i\) 都是 \(p\) 的倍数”是等价的。

所以,显然答案就是 \(\sum_{i=1}^{n-1} \min(S_i\bmod p,p-(S_i\bmod p))\),并且也可以保证 \(S_i\) 单调不减。时间复杂度 \(\mathcal{O}(n\omega(n))\)

\(*\) CF Round 604 Div.1

做出 A,B,赛后五分钟做出 C。

B. Beautiful Sequence

首先将所有 \(0,2\) 按顺序排起来,得到 \(00\dots0022\dots22\) 这样的序列,然后有两种情况:

  1. 第一个 \(1\)\(3\) 插入在开头;
  2. 第一个 \(1\)\(3\) 插入在开头的后面一个位置。

分类讨论这两种情况,然后检查是否符合要求。

代码:https://codeforces.com/contest/1264/submission/157810494

C. Beautiful Mirrors with queries

假如没有修改,设 \(f_i\) 为顺利通过 \(i\) 所需的期望步数,那么 \(f_i=p_i(f_{i-1}+1)+(1-p_i)(f_{i-1}+f_i+1)\)。解得 \(f_i=\frac{f_{i-1}+1}{p_i}\),也即 \(f_i=\sum_{k=1}^i (\prod_{j=k}^i p_j)^{-1}\)。通过一点预处理,就能 \(\mathcal{O}(1)\) 求出通过一段区间的期望步数。

所以用 std::set 维护即可。

\(*\) CF Round 733 (Div.1 + Div.2)

做出 A ~ D,赛后做出 E。

D. Secret Santa

一开始写了个基环树 dp,还写错了。

首先,设 \(a\) 中不同的数字有 \(k\) 种,答案恰好可以取到 \(k\)

设答案是 \(p_1,p_2,\dots,p_n\),我们钦定任意 \(k\) 个位置 \(i_1,i_2,\dots,i_k\),使得 \(a_{i_1},a_{i_2},\dots,a_{i_k}\) 两两不等,并使得这些位置的 \(p_{i_x}=a_{i_x}\)。记 \(b_1,b_2,\dots,b_{n-k}\) 表示此时还没确定 \(p\) 的位置,\(c_1,c_2,\dots,c_{n-k}\) 表示此时还没被使用的位置。

然后有两种情况:

  1. 假如 \(k=n-1\)\(b_1=c_1\),那么除 \(b_1\) 以外的所有元素形成了一个环,需要略微调整这个环使得 \(b_1\) 被 fulfilled。
  2. 否则,这里有一种有趣的做法:随机打乱 \(b_1,b_2,\dots,b_{n-k}\),如果 \(\forall i,b_i\neq c_i\) 的话,就停止,否则再次打乱。这个过程期望只需要做 \(e\approx 3\) 次。

E. Minimax

分五种情况讨论。吐了。

Edu Round 129

做出 A ~ D。

\(*\) CF Round 606 Div.1

做出 ABC。

C. Beautiful Rectangle

设序列中 \(x\) 的出现次数是 \(c_x\),有一个结论:设矩形大小为 \(h\times w\)\(hw=n\),假如 \(\max\limits_x \{c_x\}\le \min(h,w)\),那么序列中的所有数都可以放在这个矩形中。

这是因为,在最坏形况下,所有数的出现次数都等于 \(\min(h,w)\)。不妨设 \(h<w\),那么考虑如下形式的构造即可:

\[\begin{matrix} 1 & 2 & \dots & w-2 & w-1 & w\\ 2 & 3 & \dots & w-1 & w & 1\\ 3 & 4 & \dots & w & 1 & 2\\ \vdots & \vdots & \ddots & \vdots & \vdots & \vdots\\ \end{matrix} \]

假如有一些数的出现次数 \(<\min(h,w)\),那么可以钦定每 \(\min(h,w)\) 个为一组,并认为每组内的数相同。

所以枚举 \(h\times w\) 并找到 \(h\)\(w\) 最接近的情况,对于 \(h\times w\) 最大、且所有数都可以放进去的方案,按照上面的方法构造即可。

代码

\(*\) CF Round 609 Div.1

做出 A。

B. Domino for Young

将杨表黑白染色,可以发现一个多米诺骨牌恰好覆盖一个黑格和一个白格。设黑格的数量是 \(c_1\),白格的数量是 \(c_2\),答案的上界就是 \(\min(c_1,c_2)\)

将相邻的黑格和白格连边,然后做二分图最大匹配。假如存在一个黑格 \(u\) 和一个白格 \(v\) 没有匹配,我们将二分图上 \(u\to v\) 的路径上的边全部取反,即可让它们匹配。所以答案就是 \(\min(c_1,c_2)\)

CF Round 795 Div.2

做出 A ~ D。

E. Number of Groups

用并查集维护连通块。按照右端点从小到大处理每个线段。可以发现,对于每个连通块,我们只需要记录其中右端点最大的一个红色线段和一个蓝色线段。用两个 std::multiset 维护。

对于每一条线段,在 multiset 上二分找到所有与它有交的线段,然后逐一合并这些线段所在的连通块即可。注意区分 std::setstd::multiset

代码

CF Round 800 Div.1

做出 AB。

C. Keshi in Search of AmShZ

我为啥想不到。我为啥想不到。我为啥想不到。

\(D_u\)\(u\to n\) 在最优策略下需要的天数,那么 \(D_u\) 就是没被 block 掉的 \((u,v)\)\(\max D_v\),加上被 block 掉的个数加一。

将所有边的方向反转然后 Dijkstra。开始时所有边都被 block 掉,每次从堆中取出一个点 \(u\),并更新所有与 \(u\) 相连的 \(v\) 的答案。

假如固定一个点 \(u\) 并考虑 \(D_u\) 是如何被更新的,因为 Dijkstra 的过程中,取出的点的 \(D\) 单调不减,所以当前的 \(\max D_v\) 就是最新被取出的这个点的 \(D\)。对于那些没有被取出的边,它们一定会被 block。

代码

CF Round 818 Div.2

做出 A ~ E。

CF Round 819 Div.1

做出 A ~ D。

E. Almost Perfect

观察到合法的排列 \(p\) 中只会有三种环:\(x\to x,x\to y\to x,x\to y\to (x+1)\to (y+1)\to x\)

对于前两种环和第三种环分别 DP,然后卷积起来。设 \(f_i\) 表示只考虑前两种环,且排列长度为 \(i\) 的排列个数;\(g_i\) 表示只考虑第三种环,且排列长度为 \(i\) 的排列个数。那么 \(f_i=f_{i-1}+f_{i-2}\times (i-1)\),对于任意 \(4\mid i\)\(g_i=g_{i-4}\times (i-2)\)

卷积时,我们枚举 \(g_k\),那么被包含在 \(g\) 中的 \(k\) 个点需要满足它们可以被划分为若干相邻的二元组。用组合数枚举这些二元组的开头 \(S\),需要满足:

  • \(n\not \in S\)
  • \(i\in S\implies (i+1)\not \in S\)

所以答案就是

\[\sum_{4\mid k,1\le k\le n} g_kf_{n-k}\binom{n-\frac{k}{2}}{\frac{k}{2}}. \]

Edu Round 135

做出 A ~ E。Performance 达到了 2500,并且上了 Master,可喜可贺。

CF Round 821 Div.2

做出 A ~ D2,Performance 2277。

E. Conveyor

考虑一组询问 \((t,x,y)\):我们算出有多少个时间 \(t'\le t\) 使得在 \(t'\) 时间 \((x,y)\) 上有 slime,设这个数是 \(f(t,x,y)\)。假如 \(f(t,x,y)=f(t-1,x,y)\) 则答案为 Yes,否则为 No。

考虑这个 \(f(t,x,y)\) 怎么算。注意到任意两个 slime 都不可能重合,且前 \(\max(t-x-y+1,0)\) 个 slime 都有到达 \((x,y)\) 的可能性,因此在 \((0,0)\) 处放 \(\max(t-x-y+1,0)\) 个 slime,并 DP 算出有多少个到达了 \((x,y)\) 即可。

CF Round 822 Div.2

做出 A ~ E,Performance 2313。

E. Rectangular Congruence

假如我们构造出了一个矩阵 \(A\),它除了对角线的限制不一定满足以外,其他限制均满足,那么对于所有 \(i\),把第 \(i\) 行整体加上 \(b_i-A_{i,i}\) 就可以让 \(A\) 满足对角线的限制。

而满足限制的 \(A\) 是好构造的,例如 \(A_{i,j}=ij\bmod n\)

F. Zeros and Ones

我终于学会数位 DP 的写法了,感动。

稍微推一下就可以得到,答案就是 \([0,m)\) 中整数 \(x\) 的个数,使得 \(\operatorname{popcount}(x)\not \equiv \operatorname{popcount}(x+n)\pmod 2\)。我们设 \(f_{i,j,k,lim}\) 表示考虑 \(x\) 的最低的 \(i\) 位,当前 \((\operatorname{popcount}(x)-\operatorname{popcount}(x+n))\bmod 2\) 的值是 \(j\),计算 \(x+n\) 时从 \((i-1)\) 位到 \(i\) 位的进位是 \(k\)\([x\ge m]\) 的真假是 \(lim\)\(x\) 的个数。这样就可以转移了,时间复杂度 \(O(t\log n)\)

f[0][0][0][1] = 1;
For(i, 0, B - 2) {
	int ncur = (n >> i) & 1, mcur = (m >> i) & 1;
	For(j, 0, 1) For(k, 0, 1) For(lim, 0, 1) {
		For(x, 0, 1) f[i + 1][j ^ ncur ^ k][x + ncur + k > 1][x == mcur ? lim : (x > mcur)] += f[i][j][k][lim];
	}
}
cout << f[B - 1][1][0][0] + f[B - 1][1][1][0] << '\n';

\(*\) Edu Round 136

做出 A ~ D,Performance 1885,因为 B 题在读入的时候就判断了无解并提前跳出循环了。

E. Cleaning Robot

可以发现(怎么发现的呢?),“不能有多个距离最小的点”相当于“机器人不能在连续的两列中换行”。于是剩下的就是一个简单的 DP 了。

\(*\) CF Round 824 Div.2

做出 A ~ E,Performance 2545。

E. House Planning

首先考虑如何确定 \(p_1\)\(p_2\) 的距离,因为确定距离后,\(d_1\) 中的每个元素就只能和 \(O(1)\)\(d_2\) 中的不同元素匹配了,此时将 \(d_2\) 中值相同的元素缩在一起,然后跑一个二分图最大匹配即可。

固定 \(d_1\) 中最小的那个元素,设为 \(D\)。分类讨论三种情况:

  • \(D\) 所代表的位置在 \([0,p_1]\) 间;
  • \(D\) 所代表的位置在 \((p_1,p_2]\) 间;
  • \(D\) 所代表的位置在 \((p_2,+\infty)\) 间。

每一种情况都只会导出 \(O(n)\) 种不同的 \(p_2-p_1\),于是总的可能的距离个数是 \(O(n)\) 的。对于每一种都跑一次 Dinic,总的时间复杂度就是 \(O(n^{2.5})\)

Global Round 24

做出 A ~ D,Performance 1939。感觉主要是因为太困了。

D. Doremy's Pegging Game

考虑一个结束时的局面,假如此时没被删除的点从小到大是 \(p_1,p_2,\dots,p_k\),那么一定存在一个 \(i\) 满足 \(p_i\)\(p_{i\bmod k+1}\) 之间的那段的边数大于 \(n/2\),并且显然这样的 \(i\) 至多有一个。

于是我们枚举结束局面中 \(p_i\)\(p_{i\bmod k+1}\) 间的点数 \(j\),这 \(j\) 个点需要全部被删除,且剩下的 \(n-2-j\) 个点既可以删也可以不删。我们需要计算有多少种删除这至多 \(n-2\) 个点的顺序,使得在这个过程中不出现结束局面。对于这 \(j\) 个点,枚举其中最后删的那个点 \(k\),假如 \(k\) 旁边的两段的长度都不超过 \(n/2\),那么就会贡献 \((j-1)!\) 种删法。对于剩下的那 \(n-2-j\) 个点,枚举其中有多少个被删了的点,并用组合数将它们插入到删除序列中即可。

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

E. Doremy's Number Line

首先将 \(a_1\ge k\) 以及 \(k-b_1>a_1\) 这两种情况判掉。对于剩下的情况,我们需要用 \(2\sim n\) 中的颜色给 \([k-b_1,a_1]\) 中的任意一个点染色。如果我们能给 \(x\) 染某一种颜色,那么所有 \(\le x\) 的点都能染这种颜色。所以,设 \(p=k-b_1\),只需要判断 \(p\) 是否能被染 \(2\sim n\) 中的某种颜色即可。

先将 \(2\sim n\) 中的所有颜色按照 \(a_i\) 从小到大排序。考虑一种颜色 \(i\),它最大能染色到 \(a_i+b_i\) 这个点。若 \(i<n\),那么我们可以用 \(n\)\(a_i\) 染色,然后 \(a_i+b_i\) 这个上界就能取到了。否则,有两种情况:

  • \(a_n\) 染颜色 \(n\)
  • 考虑 \([2,n-1]\) 中的颜色,设用它们能染色的最大的位置是 \(x\),给 \(\min(x,a_n)+b_n\) 染颜色 \(n\)

第二种情况显然是一个子问题,于是顺着递推一遍即可。时间复杂度 \(O(n\log n)\)

F. Doremy's Experimental Tree

分成两步:第一步确定树的结构,第二步确定边权。

确定树的结构:首先把所有 \(f_{i,i}\) 删掉。对于剩下的 \(f_{i,j}\),考虑其中的全局最大值,设它是 \(f_{u,v}\),那么 \((u,v)\) 间显然有一条边。将这条边删去,剩下的仍然是一个子问题,但此时所有能够连出环的边都不能考虑,用并查集维护连通性即可。

确定边权:单个 \(f_{i,j}\) 几乎无法提供有用的信息,考虑两个 \(f_{i,j}\) 相减。具体地,假如 \((u,v)\) 间有边,那么 \(f_{u,u}-f_{u,v}\) 就恰好是 \(v\) 的子树大小乘以 \((u,v)\) 间的边权。我们只需要做 \(n-1\) 次这个操作,所以每次暴力 DFS 出 \(v\) 的子树大小即可。

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

G. Doremy's Perfect DS Class

好妙啊。

我们只需要做 \(\log n\) 次判定问题,每次形如:对于一个 \(m\),确定 \(1\)\(p_{1\dots m}\) 中还是 \(p_{(m+1)\dots n}\) 中。

注意到题目中给的排列是 \(1\sim n\) 而非 \(0\sim (n-1)\) 的,因此对于 \(k=2\)\(Q(l,r,k)\) 询问,\(1\) 单独在一个等价类中。设 \(C(l,r)\) 表示 \(p_{l\dots r}\) 中有多少对 \((x,y)\) 满足 \(\lfloor \frac{x}{2}\rfloor=\lfloor \frac{y}{2}\rfloor\),有 \(C(l,r)=r-l+1-Q(l,r,2)\)

\(n\) 是奇数时,仅有 \(1\) 单独在一个等价类中。因此,设 \(x=m-2C(1,m)\) 表示 \(p_{1\dots m}\) 中有多少个还未配对的,\(y=n-m-2C(m+1,n)\) 表示 \(p_{(m+1)\dots n}\) 中有多少个还未配对的,如果 \(x=y+1\),说明 \(1\)\(p_{1\dots m}\) 中;否则有 \(y=x+1\),说明 \(1\)\(p_{(m+1)\dots n}\) 中。

\(n\) 是偶数时,\(n\) 也单独在一个等价类中。于是,若 \(x\neq y\),我们能直接判断应该递归到哪一边;否则,我们还需要获取 \(Q(1,m,n)\) 的值,以判断 \(n\) 在哪一边,然后递归到另一边。

若直接实现,则 \(n\) 是奇数时需要 \(2\log_2 n\) 次询问,\(n\) 是偶数时需要 \(3\log_2 n\) 次询问。但注意到我们只需要询问至多一次 \(n\) 在哪一边,所以 \(n\) 是偶数时只需要 \(2\log_2 n+1\) 次询问。

考虑如何将 \(2\log_2 n+1\) 优化到 \(2\log_2 n\)。递归时,无论如何都会递归到 \(l+1=r\) 的情况。此时我们已经知道了 \(C(1,l-1),C(1,r),C(l,n),C(r+1,n)\) 的值。分类讨论 \(p_l,p_r\) 的值:

  • \(p_l,p_r\) 中有一个与 \(p_{1\dots (l-1)}\) 中的某个在同一等价类中,则 \(C(1,l-1)+1=C(1,r)\)。此时我们只需要询问 \(C(1,l)\) 的值即可得知 \(p_l,p_r\) 中哪一个是 \(1\)
  • \(p_l,p_r\) 中有一个与 \(p_{(r+1)\dots n}\) 中的某个在同一等价类中,则同理;
  • 剩下的情况是,\(n\) 为偶数且 \(\{p_l,p_r\}=\{1,n\}\)。此时我们也可以通过一次询问来得知其中哪个是 \(1\)
posted @ 2022-09-24 18:30  Alan_Zhao_2007  阅读(129)  评论(2编辑  收藏  举报