ARC058

C

直接枚举即可。

D

∑ i = 1 n − a calc ( 1 , 1 , i , b ) calc ( i , b + 1 , n , m ) \sum_{i=1}^{n-a} \text{calc}(1,1,i,b) \text{calc}(i,b+1,n,m) i=1nacalc(1,1,i,b)calc(i,b+1,n,m)

其中 c a l c ( a , b , c , d ) calc(a,b,c,d) calc(a,b,c,d) 表示从 ( a , b ) (a,b) (a,b) ( c , d ) (c,d) (c,d) 的方案数,即 C c − a + d − b c − a C_{c-a+d-b}^{c-a} Cca+dbca

E

直接数很麻烦,还要考虑去重,非常不可做。于是考虑反向操作,即用总方案数减去不合法方案数。

总方案数很显然,为 1 0 n 10^n 10n

注意到 x + y + z ≤ 17 x+y+z \leq 17 x+y+z17,考虑状压,若当前某个后缀和为 k k k,那么让 s t ∣ = 1 < < ( k − 1 ) st|=1<<(k-1) st=1<<(k1),存储到 k ≤ 17 k \leq 17 k17 即可。

然后是简单的 d p dp dp

code

F

牛逼题。

设计一个非常显然的 DP,令 f i , j f_{i,j} fi,j 表示前 i i i 个串拼成的长度为 j j j 的最小字典序字符串,那么有 f i , j = min ⁡ ( f i − 1 , j − ∣ s t i ∣ + s t i , f i − 1 , j ) f_{i,j}=\min(f_{i-1,j-|st_i|}+st_i,f_{i-1,j}) fi,j=min(fi1,jsti+sti,fi1,j),时空复杂度为 O ( n m 2 ) \text{O}(nm^2) O(nm2),瓶颈在状态存储和字典序比较。

但是特殊的是,它比较的是字典序,对于两个都能转移到 f n , m f_{n,m} fn,m 的转移状态 f i , j , f i , k f_{i,j},f_{i,k} fi,j,fi,k(倒着跑 01 01 01 背包即可预处理),若 f i , j f_{i,j} fi,j 不为 f i , k f_{i,k} fi,k 前缀,则一定存在一方更优,可以直接舍弃。

于是我们想到在求解 f i , j f_{i,j} fi,j 时维护一个有用的转移状态集合,由于这些串存在前缀关系,故可以用单调栈维护。
设栈顶串为 g i g_i gi,则栈中所有串都为 g i g_i gi 前缀。

于是转移方程中的两种情况就可以看作:

1. 1. 1. g i − 1 g_{i-1} gi1 的长度为 j − ∣ s t i ∣ j-|st_i| jsti 的前缀与 s t i st_i sti 拼接。

2. 2. 2. g i − 1 g_{i-1} gi1 的长度为 j j j 的前缀。

比较字典序较轻松,可用 z z z 函数 O ( 1 ) \text{O}(1) O(1) 解决。

解决空间问题,即解决状态的存储问题,设 p i , j p_{i,j} pi,j f i , j f_{i,j} fi,j 的辅助数组,若 p i , j p_{i,j} pi,j 0 0 0,则该状态无用;若 p i , j p_{i,j} pi,j 1 1 1,说明 f i − 1 , j f_{i-1,j} fi1,j 更优;若 p i , j p_{i,j} pi,j 2 2 2,说明 f i − 1 , j − ∣ s t i ∣ + s t i f_{i-1,j-|st_i|}+st_i fi1,jsti+sti 更优。

下面只需要解决单调栈的维护问题即可。

设当前求出状态为 f i , j f_{i,j} fi,j,栈顶状态为 f i , k f_{i,k} fi,k,那么情况分为三种:

A . A. A. f i , k f_{i,k} fi,k f i , j f_{i,j} fi,j 前缀,直接将 j j j 入栈即可。

B . B. B. f i , j f_{i,j} fi,j 优于 f i , k f_{i,k} fi,k,那么使 p i , k = 0 p_{i,k}=0 pi,k=0,并不断弹出栈顶元素直至合法为止。

C . C. C. f i , j f_{i,j} fi,j 劣于 f i , k f_{i,k} fi,k,不入栈,跳过即可。

同样涉及到字典序的比较,考虑对 p p p 值进行分类讨论:

1. 1. 1. p i , j = 1 , p i , k = 1 p_{i,j}=1,p_{i,k}=1 pi,j=1,pi,k=1,那么它们都是 g i − 1 g_{i-1} gi1 的前缀,对应情况 A A A

2. 2. 2. p i , j = 1 , p i , k = 2 p_{i,j}=1,p_{i,k}=2 pi,j=1,pi,k=2,因为 f i , k = g i − 1 [ 1 ⋯ ( k − ∣ s t i ∣ ) ] + s t i f_{i,k}=g_{i-1}[1 \cdots(k-|st_i|)]+st_i fi,k=gi1[1(ksti)]+sti,那么判断 g i − 1 [ ( k − ∣ s t i ∣ + 1 ) ⋯ j ] g_{i-1}[(k-|st_i|+1) \cdots j] gi1[(ksti+1)j] s t i st_i sti 关系即可。

3. 3. 3. p i , j = 2 , p i , k = 1 p_{i,j}=2,p_{i,k}=1 pi,j=2,pi,k=1,因为 f i , j = g i − 1 [ 1 ⋯ ( j − ∣ s t i ∣ ) ] + s t i f_{i,j}=g_{i-1}[1 \cdots (j-|st_i|)]+st_i fi,j=gi1[1(jsti)]+sti,若 j − ∣ s t i ∣ ≤ k j-|st_i| \leq k jstik,那么 f i , k f_{i,k} fi,k f i , j f_{i,j} fi,j 前缀;否则需要判断 g [ ( j − ∣ s t i ∣ + 1 ) ⋯ k ] g[(j-|st_i|+1) \cdots k] g[(jsti+1)k] s t i st_i sti 的关系。

4. 4. 4. p i , j = 2 , p i , k = 2 p_{i,j}=2,p_{i,k}=2 pi,j=2,pi,k=2,因为 f i , j = g i − 1 [ 1 ⋯ ( j − ∣ s t i ∣ ) ] + s t i f_{i,j}=g_{i-1}[1 \cdots (j-|st_i|)]+st_i fi,j=gi1[1(jsti)]+sti f i , k = g i − 1 [ 1 ⋯ ( k − ∣ s t i ∣ ) ] + s t i f_{i,k}=g_{i-1}[1 \cdots(k-|st_i|)]+st_i fi,k=gi1[1(ksti)]+sti,那么我们需要先比较 g i − 1 [ ( k − ∣ s t i ∣ + 1 ) ⋯ ( j − ∣ s t i ∣ ) ] g_{i-1}[(k-|st_i|+1) \cdots (j-|st_i|)] gi1[(ksti+1)(jsti)] s t i st_i sti 的关系,若相等则再比较 s t i [ ( j − k + 1 ) ⋯ ∣ s t i ∣ ] st_i[(j-k+1) \cdots |st_i|] sti[(jk+1)sti] s t i st_i sti 的关系。

一个巧妙的方法是设 t i = s i + # + g i − 1 t_i=s_i + \# + g_{i-1} ti=si+#+gi1,然后利用 z z z 函数判断即可。

至此,时空复杂度均降至 O ( n m ) \text{O}(nm) O(nm)

code

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值