题目链接
题意
给出字符串S和T,1e5个询问,每次询问S的一段区间是否能转变成T的一段区间。
转变方式:
- A>BC A > B C
- B>AC B > A C
- C>AB C > A B
- AAA A A A 可以消除
题解
我们从以上四个条件出发推导出更加精华的条件
- B>AC>AAB>AAAC>C B > A C > A A B > A A A C > C
- C>AB>AAC>AAAB>B C > A B > A A C > A A A B > B
- A>BC>BB A > B C > B B
也就是说所有的 C C 都等价于
由于 B>AC B > A C 也就是 B>AB B > A B ,而3个 A A 可以消除,这个操作意味着B前面可以有任意多个,所以说, B B 前面的紧贴着的的数量我们可以忽略。
由于
B>AB>BBB>ABBB>BBBBB,A>BB>ABB>BBBB
B
>
A
B
>
B
B
B
>
A
B
B
B
>
B
B
B
B
B
,
A
>
B
B
>
A
B
B
>
B
B
B
B
也就是说,我们只要有一个
A
A
或者就可以在这基础上增加偶数个
B
B
。
那么问题就比较清楚了。
但是串最后的 A A 是一定要被最后的A抵消掉,因为没有操作可以生成A并且把A插入到 S[a,b] S [ a , b ] 的最后。
分如下情况讨论:
如果 S[a,b] S [ a , b ] 最后的 A A 不足以抵消掉的A,那么输出0,否则记录S[a,b]后面的A与T[a,b]的后面的A的差值,记做 delta2 d e l t a 2 。
如果 delta2=0 d e l t a 2 = 0 那么只需要比较 S[a,b] S [ a , b ] 中的 B B 的数量和中的 B B 的数量,如果中 B B 的数量大于中 B B 的数量,那么差值必定要为2的倍数,并且如果中 B B 的数量不为0,那么中 B B 的数量也必须不为0(无法从空串生成)。
如果 delta2>0 d e l t a 2 > 0 那么如果 S[a,b] S [ a , b ] 中 B B 的数量小于中B的数量,并且差值为偶数时候, S[a,b] S [ a , b ] 多出来的 A A 可以用来生成,并且多余的A作为B的前缀可以被消除掉。
如果 delta2>0 d e l t a 2 > 0 那么如果 S[a,b] S [ a , b ] 中 B B 的数量等于中B的数量,那么 delta2 d e l t a 2 一定要被3整除。这样可以通过消除来得到 T T <script type="math/tex" id="MathJax-Element-56">T</script>
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2e5+7;
char S[maxn],T[maxn];
int Q,a,b,c,d;
int sumS[maxn],sumT[maxn];
int lastS[maxn],lastT[maxn];
int main(){
scanf(" %s %s %d",S,T,&Q);
for(int i = 0;S[i];++i){
sumS[i+1] = sumS[i] + (S[i] == 'C' || S[i] == 'B');
lastS[i+1] = lastS[i];
if(S[i] == 'B' || S[i] == 'C')
lastS[i+1] = i+1;
}
for(int i = 0;T[i];++i){
sumT[i+1] = sumT[i] + (T[i] == 'C' || T[i] == 'B');
lastT[i+1] = lastT[i];
if(T[i] == 'B' || T[i] == 'C')
lastT[i+1] = i+1;
}
while(Q--){
scanf("%d%d%d%d",&a,&b,&c,&d);
int delta = sumT[d]-sumS[b]+sumS[a-1]-sumT[c-1];
int delta2 = b - max(a-1,lastS[b]) - (d - max(c-1,lastT[d]));
if(delta < 0 || delta % 2 != 0 || delta2 < 0 || delta2 == 0 && !(sumS[b] - sumS[a-1]) && delta > 0) {
putchar('0');
continue;
}
if(delta2 == 0 || delta > 0 || delta2 % 3 == 0)
putchar('1');
else
putchar('0');
}
return 0;
}