先瞎JB推一下,得到一些结论:
- B → A C → A A B → A A A C → C B\rightarrow AC \rightarrow AAB \rightarrow AAAC \rightarrow C B→AC→AAB→AAAC→C ,反过来也成立,得出 B B B 和 C C C 是等价的,可以将所有 B B B 看成 C C C 。
- C → A C → A A C → C C\rightarrow AC \rightarrow AAC \rightarrow C C→AC→AAC→C ,也就是说 C C C 前面 A A A 的个数是可以随意改变的,那么只有末尾的 A A A 对答案有影响。
- A → C C A\rightarrow CC A→CC ,那么 C C C 的个数不能减少,且只能增加 2 2 2 的倍数个。
假设
s
s
s 中
C
C
C 的个数为
a
a
a ,末尾
A
A
A 的个数为
b
b
b;
t
t
t 中
C
C
C 的个数为
c
c
c ,末尾
A
A
A 的个数为
d
d
d 。
由第
3
3
3 个结论得:
a
a
a 和
c
c
c 必须满足
a
≤
c
a\le c
a≤c 且
(
c
−
a
)
m
o
d
2
=
0
(c-a) ~mod ~2 =0
(c−a) mod 2=0 。
然后分类讨论。
- 若 a = c a=c a=c ,那么 C C C 的个数不能改变,只能把 b b b 减少 3 3 3 的倍数个。
- 若 a = 0 a=0 a=0 ,那么只要判断是否满足 b > d b>d b>d,因为我们可以把一个 A A A 变成 C C CC CC ,再去掉前面所有 A A A ,使后面 A A A 的个数等于 c c c 。
- 否则,只要判断是否满足 b ≥ d b\ge d b≥d ,理由同上。
所有量都可以 O ( n ) O(n) O(n) 求,再分类讨论一下就好啦。
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int k,n,m,Q;
int s1[N],s2[N],f1[N],f2[N];
int l1,r1,l2,r2;
char s[N],t[N];
bool Solve(int l1,int r1,int l2,int r2) {
int x=s1[r1]-s1[l1-1],y=s2[r2]-s2[l2-1];
if(x>y||((y-x)&1)) return 0;
int len1=min(f1[r1],r1-l1+1),len2=min(f2[r2],r2-l2+1);
if(x==y) {
if(len1<len2) return 0;
return !((len1-len2)%3);
}
if(!x) return len1>len2;
return len1>=len2;
}
int main() {
scanf("%s",s+1);n=strlen(s+1);
scanf("%s",t+1);m=strlen(t+1);
for(int i=1;i<=n;i++) s1[i]=s1[i-1]+(s[i]!='A'),f1[i]=s[i]=='A'?f1[i-1]+1:0;
for(int i=1;i<=m;i++) s2[i]=s2[i-1]+(t[i]!='A'),f2[i]=t[i]=='A'?f2[i-1]+1:0;
scanf("%d",&Q);
while(Q--) {
scanf("%d",&l1);scanf("%d",&r1);scanf("%d",&l2);scanf("%d",&r2);
putchar(Solve(l1,r1,l2,r2)?'1':'0');
}
return 0;
}