2020.11.16提高组模拟序列翻转 题解
Posted send-off-a-friend
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.11.16提高组模拟序列翻转 题解相关的知识,希望对你有一定的参考价值。
【2020.11.16提高组模拟】序列翻转 题解
题目简述
求一个(01)串经过k次以下的操作有多少种方案数。其中,操作(A)和(B)按照不同顺序进行((AB)、(BA))视其为不用的操作,即使(AB)互相不干扰。
定义合法序列:形如(10101...10101)的串,(i)维的合法串长度为(2i+1)。
操作方法:对一个合法序列中的所有(01)取反。
数据范围
(type) | (nle) | k | |
---|---|---|---|
(1) | (1) | (6) | (le n) |
(2) | (1) | (10) | (le n) |
(3) | (1) | (17) | (le n) |
(4) | (1) | (20) | (le n) |
(5) | (1) | (23) | (le n) |
(6) | (1) | (23) | (le n) |
(7) | (2) | (40) | (le n+1) |
(8) | (2) | (40) | (le n+1) |
(9) | (2) | (60) | (le n+1) |
(10) | (2) | (60) | (le n+1) |
(11) | (2) | (60) | (le n+1) |
(12) | (2) | (80) | (le n+1) |
(13) | (2) | (100) | (le n+1) |
(14) | (2) | (110) | (le n+1) |
(15) | (2) | (110) | (le n+1) |
(16) | (2) | (120) | (le n+1) |
(17) | (2) | (120) | (le n+1) |
(18) | (2) | (500) | (=n+1) |
(19) | (2) | (1000) | (=n+1) |
(20) | (2) | (5000) | (=n+1) |
(21) | (2) | (10^5) | (=n+1) |
(22) | (2) | (10^7) | (=n+1) |
(23) | (2) | (10^9) | (=n+1) |
(24) | (2) | (10^{18}) | (=n+1) |
(25) | (2) | (10^{18}) | (=n+1) |
题意分析
首先看到这道题目的数据范围十分有趣,可以大做文章。
Subtask1
(type=1,nle23)
显然暴力将(n^2*2^n)的爆搜进行状压写成(dp)即可通过。
Subtask2
(type=2,n,kle120)
(n)比较小,那么我们可以暴力区间(dp)。
我们对一串(10101...)枚举一段区间,反转。
可以观察之后,串变成了三个不互相干扰的独立串。
所以可以分开做。
但是这样是(n^3cdot k^3)的。
考虑优化。
只要枚举被反转的区间的左端点在哪里即可。
设g(x)表示左端点(x)被砍了一刀,但是右端点不知道在哪的方案数。(右区间要枚举)
最后合并即可。
Subtask3
(type=2,nle 10^{18},k=n+1)
打表可以发现答案就是(1*3*5*7*...*(2k-1))
即
证明也很简单玄学。每一次取出一段合法序列操作时,都会将这一个序列减少一个1。进行(n+1)次操作后,整个序列一定是全0的了。接着用组合数拆开、乘法原理乘起来就好。
但是直接阶乘无法通不过(n=10^{9})。
其实当(modle 2i+1)时,这个连乘的式子中会有一个998244353。
又因为998244353是一个质数,所以(1 imes3 imes... imes998244353 imes998244355 imes...=0)!(这个!不是阶乘哈)
中间的数据还是会T,分块打表即可。
以上是关于2020.11.16提高组模拟序列翻转 题解的主要内容,如果未能解决你的问题,请参考以下文章