[题解][LG-P6811]「MCOI-02」Build Battle 建筑大师

⟹ \Longrightarrow 原题链接

给定一个序列长度 N N N Q Q Q 个询问,每次询问给定循环大小 M M M

每次询问,先生成一个长度为 N N N 的序列,其中第 i i i 个位置为 ( i − 1 )   m o d   M + 1 (i - 1)~\mathrm{mod}~M+1 (i1) mod M+1,比如当 N = 7 , M = 3 N=7,M=3 N=7,M=3 的时候生成的的序列就是 { 1 , 2 , 3 , 1 , 2 , 3 , 1 } \{1,2,3,1,2,3,1\} {1,2,3,1,2,3,1} 。接着回答这个序列有多少本质不同的子序列。两个子序列本质不同,当且仅当子序列的长度不同或存在一个位置不同。

首先我们需要定义一个简单的规则让我们计算的时候不会算重。

对于子序列中连续的递增的一段,我们强制让它用原序列中同一个循环节生成,而相邻两个递增段使用原序列中相邻的两个循环节生成的。

比如原序列为 { 1 , 2 , 3 / , 1 , 2 , 3 / , 1 , 2 , 3 / , 1 } \{1,2,3/,1,2,3/,1,2,3/,1\} {1,2,3/,1,2,3/,1,2,3/,1},那么对于其中的一个子序列 { 1 , 2 , 3 / , 1 , 3 / , 1 } \{1,2,3/,1,3/,1\} {1,2,3/,1,3/,1},我们规定它使用位置集合 { 1 , 2 , 3 / , 4 , 6 / , 7 } \{1,2,3/,4,6/,7\} {1,2,3/,4,6/,7} 生成。

接下来考虑 d p \mathrm{dp} dp,设 f ( i ) f(i) f(i) 表示构造的子序列最后一个位置是使用原序列中第 i i i 个位置生成的,那么上一个位置就可以选 i − M + 1 i-M+1 iM+1 i − 1 i-1 i1,若选择之前的位置就违反了之前定的规则了。

那么可以得到:

f ( i ) = ∑ j = max ⁡ { i − M , 0 } i − 1 f ( j ) f(i)=\sum\limits_{j=\max\{i-M,0\}}^{i-1} f(j) f(i)=j=max{iM,0}i1f(j)

可以使用前缀和优化一下:

s ( i ) = ∑ j = 0 i f ( j ) f ( i ) = s ( i − 1 ) − s ( i − M − 1 ) s(i) = \sum\limits_{j=0}^i f(j)\\ f(i) = s(i - 1) - s(i - M - 1) s(i)=j=0if(j)f(i)=s(i1)s(iM1)

可以发现,实际上我们需要求的答案就是 s ( n ) s(n) s(n), 而根据上面的式子,可以稍微推导一下:

s ( i ) = s ( i − 1 ) + f ( i ) = 2 s ( i − 1 ) − s ( i − M − 1 ) s(i) = s(i-1) + f(i) = 2s(i - 1) - s(i - M - 1) s(i)=s(i1)+f(i)=2s(i1)s(iM1)

但是这样依然是 O ( n q ) O(nq) O(nq) 的。考虑转化一下问题。(这个东西是看题解的)
现在假设在数轴上有一个点,开始的时候在 0 0 0, 然后有一个值 v v v,开始的时候等于 0 0 0,每走一步就在答案中加上当前的 v v v,每一步有两种选择:

  1. 向右移动 1 1 1 格,然后 v v v 乘上 2 2 2
  2. 向右移动 M + 1 M + 1 M+1 格,然后 v v v 取相反数。

最终这个点要走到 n n n,那么它的答案贡献计算显然是:
a n s = ∑ i = 0 ⌊ N M + 1 ⌋ ( − 1 ) i × 2 N − ( M + 1 ) i × ( N − ( M + 1 ) i + i i ) ans = \sum\limits _{i=0} ^{\left\lfloor \frac{N}{M + 1}\right\rfloor} (-1)^i \times 2^{N - (M + 1) i} \times \binom{N - (M + 1)i + i}{i} ans=i=0M+1N(1)i×2N(M+1)i×(iN(M+1)i+i)

对于每一个 m m m ,我们都求出其答案,那么时间复杂度就是 ∑ i = 1 m m i = O ( m log ⁡ 2 m ) \sum_{i=1}^m \frac{m}{i} = O(m\log_2 m) i=1mim=O(mlog2m)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值