0%

CF-1075-D2. Little String (Hard Version)(进行更加细致的分类讨论)(对于非 2 的幂次,不额外引入任何奇数素因子,总是最好的)

题目大意

1. 题目定义

给定一个长度为 nn 的字符串 ss(由 01? 组成)和一个正整数 cc

函数 f(w)f(w) 的定义:

对于一个仅含 01 的字符串 ww,其值 f(w)f(w) 表示满足以下条件的 [0,1,,n1][0, 1, \dots, n-1] 全排列 pp 的总数:

  • 对于 1in1 \le i \le n,如果 wi=1w_i = 1,则排列 pp 中必须存在至少一个连续子段,其 MEX 值为 ii

  • 对于 1in1 \le i \le n,如果 wi=0w_i = 0,则排列 pp 中不得存在任何连续子段的 MEX 值为 ii

注:MEX(Minimum Excluded)指集合中未出现的最小非负整数。

2. 目标任务

通过将 ss 中的所有 ? 替换为 01 来构造字符串 ww。在所有满足 f(w)f(w) 不能被 cc 整除 的字符串 ww 中,计算 f(w)f(w) 的最小值

3. 输出要求

  • 输出该最小值对 109+710^9 + 7 取模的结果

  • 若不存在满足条件的 ww,则输出 1-1


4. 样例解释辅助理解

  • 样例 3 (n=4,c=100,s=1001n=4, c=100, s=1001)
    字符串固定为 10011001。此时 f(1001)=4f(1001) = 4,满足条件的排列包括 [0,2,3,1],[0,3,2,1],[1,2,3,0],[1,3,2,0][0,2,3,1], [0,3,2,1], [1,2,3,0], [1,3,2,0]。由于 44 不能被 100100 整除,答案为 44

  • 样例 7 (n=5,c=8,s=100?1n=5, c=8, s=100?1)
    若将 ? 替换为 0 得到 w=10001w=10001,经计算 f(w)=12f(w) = 12。由于 1212 不能被 88 整除,且经比较这是所有可能替换中的最小值,故输出 1212

  • 样例 2 (n=3,c=1,s=???n=3, c=1, s=???)
    无论如何替换 ?,任何整数 f(w)f(w) 都能被 11 整除。因此不存在满足 “不能被 cc 整除” 条件的 ww,输出 1-1

CF-1075-D1. Little String (Easy Version)(把序列生成的过程看成不断插入数字的过程)(插入过程可以写为一个循环,应该多少范围就多少范围,特判写在循环里面)

Untitled

思路讲解

那么是这样子的,这道题目如果把这个序列生成的这个过程看成从 0n10\sim n-1 不断插入的过程,那么如果 wi=0w_i=0,那么 ii 就插入在原来 0i10\sim i-1 之间的空当中。wi=1w_i=1,只能插入在 0i10\sim i-1 的两段。

D1 当中,我们采用如上方法得到答案。

这道题目,其实想让我们求的是在不被 cc 整除的前提下,能够得到的最小值。

那其实说白了,想让值比较小,那就除了首位,结尾,全部填 1 就完了(遇到 ?),不过现在就是这个不能被 cc 整除比较烦。

当然,除了首位,当 i1i-1 为偶数的时候,也应该填写这个 ‘1’,因为反正都要引入 22,那不如就引入一个 22

不过这道题目,其实就是一个分类讨论

对于非 2 的幂次,不额外引入任何奇数素因子,总是最好的。因此,采用这个我们之前说的策略:

那就除了首位,结尾,全部填 1 就完了(遇到 ?时)

那么对于 2 的幂次,先不断填 2 进去,发现不行了,我们就回退,乘以 i1i-1,注意逆序遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 对于 2 的幂次来说,能不引入 2 自然最好
for (int i=N-1;i>=1;--i) {
if (W[i]=='?') {
ll ans_c_backup=ans_c,ans_backup=ans;
ans_c*=2;
ans_c%=C;
ans*=2;
ans%=mod;
if (ans_c==0) { // 发现不对,回退乘以 2,乘以 i-1
ans_c=ans_c_backup;
ans=ans_backup;
ans*=(i-1);
ans%=mod;
ans_c*=i-1;
ans_c%=C;
}
}
}

不过是对于什么进行分类讨论呢?

我们上面有一些地方,加上原本的串,都已经确定了一些,把这一部分的值计算出来,我们记作 ansans。那么我们知道,ansansCC 的因子的交集就是 gcd(ans,C)\gcd(ans,C)(可以用该式子计算: gcd(ans,C)=gcd(ansmodC,C)\gcd(ans,C)= \gcd(ans\mod C,C))。那么 CC 当中还没有被消掉的因子的集合就是:

Cgcd(ans,C)\frac{C}{\gcd(ans,C)}

我们就是对还未被消掉的因子集合进行分类讨论

AC代码

AC

https://codeforces.com/contest/2189/submission/360006878

心路历程(WA,TLE,MLE……)