【Atcoder】AGC012 B-F简要题解

*B.Splatter Painting

很容易联想到一种模型:

对于 v i v_i vi相同的操作,有用的最多只有 d ( d ≤ 10 ) d(d\leq 10) d(d10)个(相当于按时间戳维护了一个 d i d_i di递减的单调栈)

但每个点向外暴力染色在稠密图上复杂度依旧是 O ( n 2 ) O(n^2) O(n2)的。

需要找到一种方法使得复杂度降到 n d nd nd,考虑被染色点:

发现实际上每个点被染色的操作中只有 d d d个有用的,倒着加操作xjb D F S DFS DFS即可。


C.Tautonym Puzzle

字符集 100 100 100 ∣ S ∣ ≤ 200 |S|\leq 200 S200显然就是每个字符出现两次的倍增构造:

一开始想成 112233... 112233... 112233...然而长度也是 2 n 2^n 2n级别的,真是zz。。。

正解:

设现在前半部分为 X X X,后半部分为 Y Y Y,考虑插入一个未出现的 c c c c X c Y → a n s × 2 cXcY\to ans\times 2 cXcYans×2 c X Y c → a n s + 1 cXYc\to ans+1 cXYcans+1(为什么不是 c c X Y ccXY ccXY?形式不优美呀)


D.Colorful Balls

非常重要的一条性质(传递性):
a , b a,b a,b都能与 c c c交换,那么 a , b a,b a,b也能交换。

所以取出所有能与同色最轻球直接或间接地交换的球(间接就是通过异色最轻球),这些球之间都可以重排,组合数算一下排列。


*E.Camel and Oases

显然只有 log ⁡ v \log v logv次跳跃:
把第 i i i次跳跃能互相到达的点连起来,就是一段段区间。预处理 l e f t [ i , j ] , r i g h t [ i , j ] left[i,j],right[i,j] left[i,j],right[i,j]表示点 i i i在已经跳跃 j j j次后能走到的最左/右点。

问题转化为:
钦定第一次跳跃前的区间,剩下每层选一个区间,判断能否覆盖所有点。
假设第一次选择的区间为 [ l , r ] [l,r] [l,r],则需要用剩下 log ⁡ v \log v logv个操作覆盖 [ 1 , l ) , ( r , n ] [1,l),(r,n] [1,l),(r,n]

因为可以左右横跳,所以枚举 s s s集合状压DP f [ S ] f[S] f[S]表示 S S S集合中的跳跃可以覆盖的最大的 [ 1 , i ] [1,i] [1,i]的区间, g [ S ] g[S] g[S]表示可以覆盖的最大的 [ j , n ] [j,n] [j,n]区间。

合并处理出 m i i mi_i mii表示用部分集合覆盖 [ 1 , i ] [1,i] [1,i]时,最小的 x x x满足 [ x , n ] [x,n] [x,n]能被完全覆盖。

时间复杂度 O ( n log ⁡ v ) O(n\log v) O(nlogv)


*F.Prefix Median

a i a_i ai排序后得到两个关键性质:

  • a i ≤ b i ≤ a 2 n − i a_{i}\leq b_i\leq a_{2n-i} aibia2ni
  • 不存在 i < j i<j i<j,满足 b j < b i < b j + 1 b_j<b_i<b_{j+1} bj<bi<bj+1 b j > b i > b j + 1 b_j>b_i>b_{j+1} bj>bi>bj+1

显然 i i i越大, b i b_i bi的限制越多。
考虑倒序 d p [ i ] [ l ] [ r ] dp[i][l][r] dp[i][l][r]表示处理到 b [ i ] b[i] b[i],可选范围中 ≤ b i \leq b_i bi的数有 l l l个, > b i >b_i >bi的数有 r r r个的方案数。

注意细节
代码

你可能感兴趣的:(妙,计数DP,状压DP,atcoder)