【CF1684H】Hard Cut——从宏观到微观,不断地子问题转化,无与伦比的构造题

11 篇文章 0 订阅
6 篇文章 0 订阅

× 3400 \times 3400 ×3400 的神仙题,做自闭了。

Description

给定一个长度为 n n n 01 01 01 串,你需要将它划分为若干个子串,使得将各个子串对应的二进制数加在一起,得到的是 2 2 2 的若干次幂。

数据范围: 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106,时限 2.00s \texttt{2.00s} 2.00s

Solution

Part 0: 何时无解

首先,我们考虑何时无解。令 k k k s s s 1 1 1 的数量。

k = 0 k=0 k=0 时显然无解,那么 k > 0 k>0 k>0 呢?我们不妨打个表,考虑所有 k ≠ 0 k \neq 0 k=0 的串,并通过二进制枚举划分来判断是否有解。然而,我们连一个无解的序列都找不到!!1

因此,我们果断猜想: k ≠ 0 k \neq 0 k=0 时都是有解的。这个猜想将会在下面的构造中被逐渐证明。不过,在被证明之前,我们有必要在潜意识里把它当做定理来对待,因为只有这样,我们才能拥有不断构造,不断尝试的勇气。

Part 1: k k k 很小时的分析

首先,若 k = 0 k=0 k=0,显然无解;若 k = 1 / 2 / 4 k=1/2/4 k=1/2/4,则直接划分为若干个 1 1 1 即可。

接着考虑 k = 3 k=3 k=3 的情况。

  • 3 3 3 1 1 1 连在一起,则划分为 ( 11 ) 2 , ( 1 ) 2 (11)_2,(1)_2 (11)2,(1)2,和为 4 4 4
  • 否则,找出一个之后是 0 0 0 1 1 1,则划分为 ( 1 ) 2 , ( 1 ) 2 , ( 10 ) 2 (1)_2,(1)_2,(10)_2 (1)2,(1)2,(10)2,和为 4 4 4

然后考虑 k = 5 k=5 k=5 的情况。

  • 5 5 5 1 1 1 连在一起,则划分为 ( 1111 ) 2 , ( 1 ) 2 (1111)_2,(1)_2 (1111)2,(1)2,和为 16 16 16
  • 否则,至少存在一个形如 ( 100 ) 2 (100)_2 (100)2 ( 101 ) 2 (101)_2 (101)2 的子串。若存在 ( 100 ) 2 (100)_2 (100)2,则划分为 ( 100 ) 2 , 1 2 , 1 2 , 1 2 , 1 2 (100)_2,1_2,1_2,1_2,1_2 (100)2,12,12,12,12;否则,划分为 ( 101 ) 2 , 1 2 , 1 2 , 1 2 (101)_2,1_2,1_2,1_2 (101)2,12,12,12,和为 8 8 8

Part 2: 子问题转化

我们不妨结合子问题递归的思想,将 k k k 较大的情况给转化为 k k k 较小的子问题,这样需要考虑的 k k k 就不再是无穷无尽的了。

令问题 f ( l , r , s ) f(l,r,s) f(l,r,s) 表示,对于子串 s [ l , r ] s[l,r] s[l,r],要求构造出一组划分方案,使各个划分串的和为 s s s。特别的,初始状态为 f ( 1 , n , 2 ⌈ log ⁡ 2 k ⌉ ) f(1,n,2^{\lceil \log_2 k \rceil}) f(1,n,2log2k)

思考如何将 f ( l , r , s ) f(l,r,s) f(l,r,s) 划分为若干子问题。考虑分治,每次将 [ l , r ] [l,r] [l,r] 给切成两段,使得两段中 1 1 1 的数量之差不超过 1 1 1,并令两个子问题的 s ′ s' s 均为 s 2 \frac s 2 2s。不难发现, s ′ s' s 始终为 2 ⌈ log ⁡ 2 k ⌉ 2^{\lceil \log_2 k \rceil} 2log2k,读者自证不难。

在不断分治的过程中,可不可能出现无解的情况呢?当然可能。比如分治到了一个包含 5 5 5 1 1 1 的区间,该区间中 5 5 5 1 1 1 是连在一起的,然而 k = 2 ⌈ log ⁡ 2 5 ⌉ = 8 k=2^{\lceil \log_2 5 \rceil}=8 k=2log25=8,从而就无解了。然而,根据 Part 0,应该是有解才对啊。所以,当 k ∈ [ 6 , 11 ] k \in [6,11] k[6,11] 时,不能直接分治,因为可能会误判为无解。

现在, k ∈ [ 6 , 11 ] k \in [6,11] k[6,11] 是不能分治了,那 k ∈ [ 12 , n ] k \in [12,n] k[12,n] 呢?我们暂且先不管它们,毕竟,如果我们对 k ∈ [ 6 , 11 ] k \in [6,11] k[6,11] 都构造出了解,那么这题就被解决了。

Part 3: 对 k = 6 , 7 , 8 , 9 , 10 , 11 k=6,7,8,9,10,11 k=6,7,8,9,10,11 的初步解决

此时的 k k k 较小,下面的主要思考方法是,不断地给出不同的构造方案,直到覆盖所有的情况。

k = k= k= s = s= s=做法
68见 Part 3.1
78见 Part 3.1
88见 Part 3.1
916见 Part 3.2
1016见 Part 3.3
1116见 Part 3.1
711见 Part 4.2
48见 Part 4.1

Part 3.1

Lemma:若 s ∈ [ k , ⌊ 1.5 k ⌋ ] s \in [k,\lfloor {1.5k} \rfloor] s[k,1.5k],则必然有解。

  • 1 1 1 的位置分别为 p 1 , p 2 , ⋯   , p k p_1,p_2,\cdots,p_k p1,p2,,pk,并考虑每一对 ( p 1 , p 2 ) , ( p 3 , p 4 ) , ⋯ (p_1,p_2),(p_3,p_4),\cdots (p1,p2),(p3,p4),特别的,若 k k k 为奇数,则 p k p_k pk 无法被配对,于是直接将它断成一段,对总和的贡献为 1 1 1
  • 假设现在正在考虑 ( p u , p v ) (p_u,p_v) (pu,pv)。显然的,它们俩必然可以对总和贡献 2 2 2。与此同时,若它们连续,则也可以对总和贡献 3 3 3 ( 11 ) 2 = 3 10 (11)_2=3_{10} (11)2=310);若不连续,则也能对总和贡献 3 3 3 ( 10 ) 2 + ( 1 ) 2 = 3 10 (10)_2+(1)_2=3_{10} (10)2+(1)2=310
  • 从而,不难证明原引理。

这样一来, k = 6 / 7 / 8 / 11 k=6/7/8/11 k=6/7/8/11 的情况就被解决了。

Part 3.2

Part 3.2 中,我们考虑 k = 9 , s = 16 k=9,s=16 k=9,s=16 的情况。考虑找出串中的第一个 0 0 0,并取出以其为开头的长度为 3 3 3 的子串 s 0 s_0 s0

  • s 0 = ( 100 ) 2 s_0=(100)_2 s0=(100)2,则转化为子问题 ( k ′ = 8 , s ′ = 12 ) (k'=8,s'=12) (k=8,s=12),使用 Part 3.1 即可解决。
  • s 0 = ( 101 ) 2 s_0=(101)_2 s0=(101)2,则转化为子问题 ( k ′ = 7 , s ′ = 11 ) (k'=7,s'=11) (k=7,s=11),以后再做讨论。
  • s 0 = ( 110 ) 2 s_0=(110)_2 s0=(110)2,则转化为子问题 ( k ′ = 7 , s ′ = 10 ) (k'=7,s'=10) (k=7,s=10),使用 Part 3.1 即可解决。
  • s 0 = ( 111 ) 2 s_0=(111)_2 s0=(111)2,则转化为子问题 ( k ′ = 6 , s ′ = 9 ) (k'=6,s'=9) (k=6,s=9),使用 Part 3.1 即可解决。

Part 3.3

Part 3.3 中,我们考虑 k = 10 , s = 16 k=10,s=16 k=10,s=16 的情况。

此时,若继续采用 Part 3.2 的做法,那么你会发现,没有一个子问题能使用 Part 3.1 解决。此时,我们不妨回顾一下 Part 2,尝试直接分治下去,不做任何其他花里胡哨的东西。

考虑找到第 4 4 4 1 1 1 并从这里断开,并转化为 ( k ′ = 4 , s ′ = 8 ) (k'=4,s'=8) (k=4,s=8) ( k ′ = 6 , s ′ = 8 ) (k'=6,s'=8) (k=6,s=8) 的情况。前者以后再做讨论,后者可以套用 Part 3.1 解决。

Part 4: 最后两种情况

Part 4.1: k = 4 , s = 8 k=4,s=8 k=4,s=8

将子问题转化的思想贯彻到底!!1

我们像 Part 3.2 那样,找出串中的第一个 1 1 1,并取出以其为开头的长度为 3 3 3 的子串 s 0 s_0 s0

  • s 0 = ( 100 ) 2 s_0=(100)_2 s0=(100)2,则转化为 ( k ′ = 3 , s = 4 ) (k'=3,s=4) (k=3,s=4) 的情况,调用 Part 3.1 即可解决。
  • s 0 = ( 101 ) 2 s_0=(101)_2 s0=(101)2,则转化为 ( k ′ = 2 , s = 3 ) (k'=2,s=3) (k=2,s=3) 的情况,调用 Part 3.1 即可解决。
  • s 0 = ( 110 ) 2 s_0=(110)_2 s0=(110)2,则转化为 ( k ′ = 2 , s = 2 ) (k'=2,s=2) (k=2,s=2) 的情况,调用 Part 3.1 即可解决。
  • s 0 = ( 111 ) 2 s_0=(111)_2 s0=(111)2,则再拼上最后的那个 1 1 1,根据 ( 111 ) 2 + 1 2 = 8 10 (111)_2+1_{2}=8_{10} (111)2+12=810 即可解决。

Part 4.1: k = 7 , s = 11 k=7,s=11 k=7,s=11

转化为 ( k 1 = 4 , s 1 = 8 ) (k_1=4,s_1=8) (k1=4,s1=8) 以及 ( k 2 = 3 , s 2 = 3 ) (k_2=3,s_2=3) (k2=3,s2=3) 的两个子问题即可解决。


综上所述,本题被解决,时间复杂度 O ( n log ⁡ n ) O(n \log n) O(nlogn) O ( n ) O(n) O(n)

Code

咕咕咕

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值