当前位置 博文首页 > Wings:2020-2021 ICPC 亚洲区域赛 济南站 L.Bit Sequence
我搬运我自己应该算原创吧
题目
设 f ( x ) f(x) f(x)为 x x x二进制下 1 1 1的个数. 给出长度为 m m m的 01 01 01序列 a a a, 给出 L L L, 求有多少个 x ∈ [ 0 , L ] x \in [0, L] x∈[0,L], 满足 f ( x + i ) m o d ?? 2 = a i f(x + i) \mod 2 = a_i f(x+i)mod2=ai?
1 ≤ m ≤ 100 , 0 ≤ L ≤ 1 0 18 1 \le m \le 100, 0 \le L \le 10^{18} 1≤m≤100,0≤L≤1018
设 g ( i ) = f ( i ) m o d ?? 2 g(i) = f(i) \mod 2 g(i)=f(i)mod2
我们把 g ( i ) g(i) g(i)求出 [ 0 , L + m ] [0, L+m] [0,L+m]个, 排成一排, 然后就类似于字符串匹配一样统计个数.
注意到 L L L很大, 我们没办法把这个序列全部求出来. 所以这个序列一定有规律.
注意到, 当 i ∈ [ 2 k ? 1 , 2 k ) i \in [2^{k-1}, 2^k) i∈[2k?1,2k)时, 有 f ( i + 2 k ) = f ( i ) + 1 f(i + 2^k) = f(i) + 1 f(i+2k)=f(i)+1, 也就是相当于 i i i的二进制下的第 k k k位从 0 0 0变成 1 1 1, 所以有 g ( i + 2 k ) = g ( i ) ⊕ 1 g(i + 2^k) = g(i) \oplus 1 g(i+2k)=g(i)⊕1. 这样, 我们就发现了序列 g g g的构造方式:
第一个是0, 然后把当前序列取反, 拼在后面. 如下:
0
01
0110
01101001
0110100110010110
...
还注意到 m m m 很小, 只有 100 100 100, 而 2 7 = 128 2^7 = 128 27=128. 所以我们可以先构造出 g g g的前 128 128 128位, 更大的数一定会包含这个序列多次. 用 h ( i ) h(i) h(i)表示 g g g的前 2 i 2^i 2i位的序列, h ′ ( i ) h'(i) h′(i)表示 h ( i ) h(i) h(i)每一位取反的序列.
很容易知道 h ( 8 ) = h ( 7 ) + h ′ ( 7 ) h(8) = h(7) + h'(7) h(8)=h(7)+h′(7). 为方便, 令 A = h ( 7 ) , A ′ = h ′ ( 7 ) A = h(7), A' = h'(7) A=h