0%

AGC048 简要题解

A - atcoder < S

随便做,我的做法是枚举 \(S\)\(\tt{atcoder}\) 的前缀,然后一次一定是把最靠近的目标字符转移过来。

提交记录

B - Bracket Score

如果把所有奇数位置上的 \(A\)\(B\) 调换,那么某种选择每一位是 \(A\) 还是 \(B\) 的方案合法当且仅当选了新的 \(A\)\(B\) 中各 \(\dfrac{n}{2}\) 个数。证明考虑一对匹配的括号中间一定夹着偶数个括号,所以一定是一个 \(A\) 一个 \(B\),充分性考虑把相邻的 \(AB\)\(BA\) 合成一对括号,然后删掉这两个元素,一直做下去一定能消完,显然这样方案合法。所以随便上个贪心(我用的是先把较大的选了然后按差值调整)就行了。

提交记录

C - Penguin Skating

如果我们定义 \(x_i,0\leqslant i\leqslant n\) 为开始局面第 \(i\) 和第 \(i+1\) 企鹅之间的空位个数(认为两端加上两只占位用企鹅), \(y_i\) 同理是结束局面的情况。那么我们每一次操作就是选择一个 \(i\),然后让 \(x_{i-1}:=x_{i-1}+x_i\)\(x_{i+1}:=x_{i+1}+x_i\)。所以最终局面的 \(y_i\) 每一个都对应原 \(x\) 序列的一段区间的和,且都是按顺序的。所以我们只需要用双指针扫一遍每个 \(y_i\) 对应的区间,复杂度 \(O(n)\),注意当两端为 \(0\) 时由于保证移动次数最小要往里缩。

提交记录

D - Pocky Game

我们发现一个人取石子一定是一次取一颗或者是取完一堆,因为取一颗可以到达所有取多颗但取不满的后继局面,一定不劣。同时,如果轮到某一个人取,那么他能取的那堆石子越多越好。

定义 \(fl(l,r)\) 表示现在还剩下 \([l,r]\) 中的石子没有被取,轮到第一个人先手,这时 \(a_l\) 至少为多少才能保证第一个人必胜(假设我们可以随意改变 \(a_l\) 的值,但是其它的值固定),类似地,\(fr(l,r)\) 为让 \(r\) 先手 \(a_r\) 至少多少保证第二个人必胜。则第一个人必胜当且仅当 \(fl(1,n)\leqslant a_1\)

我们考虑 \(fl\) 的转移,\(fr\) 的转移类似:

  • \(fr(l+1,r)>a_r\) 时,我们直接把 \(l\) 这一堆取完就行了,所以此时 \(fl(l,r)=1\)
  • 反之两个人一定是一个一个取,分别考虑一个人只会机械地取一个,另外一个人要多久才能到达必胜状态:假设最左面的石子堆有 \(x\) 个石子,对于第一个人,第二个人取了 \(a_r-fr(l+1,r)+1\) 个后可以直接取完;对于第二个人,第一个人取了 \(x-fl(l,r-1)+1\) 个后可以直接取完,所以有 \[ a_r-fr(l+1,r)+1+1\leqslant x-fl(l,r-1)+1\\ x\geqslant fl(l,r-1)-fr(l+1,r)+a_r+1 \]\(fl(l,r)=fl(l,r-1)-fr(l+1,r)+a_r+1\)

所以单组数据复杂度为 \(O(n^2)\)

提交记录

E - Strange Relation

官方题解中文翻译版

首先有一个结论:假设给定了 \(A,T\) 欲求 \(f(A,T)\),令 \(z_i=A_i+Tx_i\),则对于字典序最大的 \(x\),一定不存在一个 \(i>1\),使得 \(A_1-T<z_i\leqslant A_1\)。如果存在,我们选择那个最靠前的 \(i\),让其 \(x_i\) 变大,然后我们一定可以通过调整使得新的 \(x\) 也满足要求,这样字典序会变大。

然后我们考虑从 \(x=f(A,T)\) 递推出 \(x'=f((A_2,A_3,\dots,A_n),T)\)。具体地,对任意 \(i>1\),若 \(A_i+Tx_i>A_1\),则 \(x'_{i-1}=x_i-1\),反之 \(x'_{i-1}=x_i\)。不难发现,这样的构造一定是正确的。

同时,既然我们能从 \(x\) 推出 \(x'\),反过来用这个方法我们也可以从 \(x'\) 推出 \(x\),同时,如果 \(x'\) 是字典序最大的,那么由其推出的 \(x\) 也是字典序最大的。所以我们尝试从 \(f((A_2,A_3,\dots,A_n),T)\) 推出 \(f(A,T)\)

\(g(A,T)\) 表示 \(f(A,T)\) 的最后一个元素。我们注意到,其只与 \(g((A_2,A_3,\dots,A_n),T)\)\(A_1\)\(A_n\) 有关,所以我们就可以设一个 dp,先枚举 \(A_n\),然后设 \(dp(i,j)\) 为考虑了 \((A_i,\dots,A_n)\)\(g((A_i,\dots,A_n),T)=j\) 的方案数,转移枚举 \(A_{i-1}\) 直接转移即可。

然后对于其它位置的值,我们都可以类似做一遍 dp 得到。这样总复杂度 \(O(n^3k^2)\)

提交记录

F - 01 Record

我们首先把 \(S\) 翻转,然后把过程倒过来,那么每一个数都对应了一个子序列 10101...。我们把这样 1 开头,10 交替出现的子序列称为“好的”。然后我们每一次从 \(S\) 中删去最长的好的子序列,不难发现如果最后有 0 剩下一定无解;反之我们得到了一个序列 \(\{l_n\}\),代表每一次删去的子序列的长度,显然该序列单调不增。

假设一开始被写在黑板上的数是 \(x_1,x_2,\dots,x_m(x_1\geqslant x_2\geqslant \dots \geqslant x_m)\),我们考虑判断这组 \(x\) 是否合法:首先一定有 \(\sum l_i=\sum x_i\),然后考虑一定有 \(x_1\leqslant l_1\),扩展到更一般的情况,考虑任何一个前缀 \(x_1,x_2,\dots,x_i\),一定有 \[ \sum\limits_{i=1}^i \lfloor\frac{x_i}{2}\rfloor\leqslant \sum\limits_{i=1}^i \lfloor\frac{l_i}{2}\rfloor\\ \sum\limits_{i=1}^i \lceil\frac{x_i}{2}\rceil\leqslant \sum\limits_{i=1}^i \lceil\frac{l_i}{2}\rceil \] 即前 \(i\) 个数中因抹掉而产生的 0/1 一定不大于前 \(i\) 个好的子序列的 0/1。必要性比较显然,因为前 \(i\) 个数最多只能对应 \(i\) 个子序列,按照子序列的长度从大到小排序一定会让限制最松,而这种情况都不满足的话就一定无解。

可以证明,这也是 \(x\) 合法的充分条件,证明见官方题解

所以我们可以设计一个 dp,我们按 \(x_i\) 降序填入,设 \(f(i,j,a,b)\) 表示现在填了 \(i\)\(x\) 序列中的数,最后一个数是 \(j\)\(\lfloor\dfrac{x_i}{2}\rfloor=a\)\(\lceil\dfrac{x_i}{2}\rceil=b\) 的方案数。注意到我们是降序填的,所以一定有 \(ij\leqslant |S|\),所以前两位的状态数是 \(O(|S|\log|S|)\) 的,转移可以用前缀和优化至 \(O(1)\),所以总复杂度 \(O(|S|^3\log|S|)\)

提交记录