题目链接
Picking String
题意
给出字符串S和T,1e5个询问,每次询问S的一段区间是否能转变成T的一段区间。
转变方式:
- A>BCA>BC
- B>ACB>AC
- C>ABC>AB
- AAAAAA可以消除
题解
我们从以上四个条件出发推导出更加精华的条件
- B>AC>AAB>AAAC>CB>AC>AAB>AAAC>C
- C>AB>AAC>AAAB>BC>AB>AAC>AAAB>B
- A>BC>BBA>BC>BB
也就是说所有的CC都等价于
由于B>ACB>AC也就是B>ABB>AB,而3个AA可以消除,这个操作意味着B前面可以有任意多个,所以说,BB前面的紧贴着的的数量我们可以忽略。
由于B>AB>BBB>ABBB>BBBBB,A>BB>ABB>BBBBB>AB>BBB>ABBB>BBBBB,A>BB>ABB>BBBB也就是说,我们只要有一个AA或者就可以在这基础上增加偶数个BB。
那么问题就比较清楚了。
但是串最后的AA是一定要被最后的A抵消掉,因为没有操作可以生成A并且把A插入到S[a,b]S[a,b]的最后。
分如下情况讨论:
如果S[a,b]S[a,b]最后的AA不足以抵消掉的A,那么输出0,否则记录S[a,b]后面的A与T[a,b]的后面的A的差值,记做delta2delta2。
如果delta2=0delta2=0那么只需要比较S[a,b]S[a,b]中的BB的数量和中的BB的数量,如果中BB的数量大于中BB的数量,那么差值必定要为2的倍数,并且如果中BB的数量不为0,那么中BB的数量也必须不为0(无法从空串生成)。
如果delta2>0delta2>0那么如果S[a,b]S[a,b]中BB的数量小于中B的数量,并且差值为偶数时候,S[a,b]S[a,b]多出来的AA可以用来生成,并且多余的A作为B的前缀可以被消除掉。
如果delta2>0delta2>0那么如果S[a,b]S[a,b]中BB的数量等于中B的数量,那么delta2delta2一定要被3整除。这样可以通过消除来得到TT<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;
}