题目大意
题目描述
给定两个以二进制字符串形式表示的非负整数 s 和 t。
请计算有多少组整数对 (a,b) 满足:
-
取值范围:a 和 b 均在区间 [s,t] 内。
-
满足等式:a×b=(a or b)×(a and b)
其中 or 表示按位或运算,and 表示按位与运算。
最终答案需要对 998244353 取模。
输入格式
第一行包含一个整数 Q(1≤Q≤20),表示测试用例的数量。
接下来 Q 行,每行包含两个 01 字符串 S 和 T,分别表示非负整数 s 和 t 的二进制形式。
数据保证 s 和 t 的二进制形式无前导零,且满足 s≤t,1≤∣S∣,∣T∣≤5×105。
输出格式
对于每个测试用例,输出一行一个非负整数,表示满足条件的解的数量对 998244353 取模后的值。
样例数据
输入
1 2 3 4 5 6 7
| 6 11 1000 1000 1001 0 100 11 111 10 111 0 11111
|
输出
样例解释
原题未提供具体的样例解释内容,此处按要求对样例数据的完整输入输出进行展示。
思路讲解
这道题目的数的规律我们很容易从这个打表看出来。
我们下面只打印了有序对:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| [-] FAILURE: RUNTIME ERROR i = [0] j = [1] bitset<10>(i) = [0000000000] bitset<10>(j) = [0000000001]
----------- i = [0] j = [2] bitset<10>(i) = [0000000000] bitset<10>(j) = [0000000010]
----------- i = [0] j = [3] bitset<10>(i) = [0000000000] bitset<10>(j) = [0000000011]
----------- i = [0] j = [4] bitset<10>(i) = [0000000000] bitset<10>(j) = [0000000100]
----------- i = [1] j = [3] bitset<10>(i) = [0000000001] bitset<10>(j) = [0000000011]
----------- i = [2] j = [3] bitset<10>(i) = [0000000010] bitset<10>(j) = [0000000011]
----------- cnt = [6]
|
不难看出,我们所要求的是:

当然,如果你要推出这个东西的话,你需要知道一个定理:

对于任意两个非负整数 a 和 b,我们设 x=a or b,y=a and b。
在位运算中,有一个非常经典的定律,即它们的和永远保持不变:
x+y=a+b
为什么? 我们可以单独看某一个二进制位:
-
如果 a 和 b 这一位都是 0,那么 x 是 0,y 也是 0。(0+0=0+0)
-
如果 a 和 b 这一位都是 1,那么 x 是 1,y 也是 1。(1+1=1+1)
-
如果 a 和 b 这一位是一个 1 一个 0,那么 x (OR) 会拿到这个 1,y (AND) 是 0。(1+0=1+0)
可以看出,无论哪种情况,进位和本质的值都不会丢失,所以 a or b 加上 a and b 必定等于 a+b。
接着,我们把这两个式子联立,可以得到:

那么不难得到:

不过更难的应该是更进一步的这个求解。
HDU - 2089- 不要62
这道题目和普通的数位 dp 最大的不同的就是,你一定要同时考虑这个低位和高位。

具体而言,为什么相减会出现问题呢?

那么我们上面讲了不能这么做,然后下面我们来讲讲应该怎么做。

AC代码
心路历程(WA,TLE,MLE……)