time limit per test : 2 seconds
memory limit per test : 256 megabytes
Alice has a string consisting of characters ′ A ′ 'A' ′A′, ′ B ′ 'B' ′B′ and ′ C ′ 'C' ′C′. Bob can use the following transitions on any substring of our string in any order any number of times:
A -> BC
B -> AC
C -> AB
AAA -> empty string
Note that a substring is one or more consecutive characters. For given queries, determine whether it is possible to obtain the target string from source.
The first line contains a string S ( 1 ≤ ∣ S ∣ ≤ 1 0 5 ) S (1 ≤ |S| ≤ 10^5) S(1 ≤ ∣S∣ ≤ 105). The second line contains a string T ( 1 ≤ ∣ T ∣ ≤ 1 0 5 ) T (1 ≤ |T| ≤ 10^5) T(1 ≤ ∣T∣ ≤ 105), each of these strings consists only of uppercase English letters ′ A ′ 'A' ′A′, ′ B ′ 'B' ′B′ and ′ C ′ 'C' ′C′.
The third line contains the number of queries Q ( 1 ≤ Q ≤ 1 0 5 ) Q (1 ≤ Q ≤ 10^5) Q(1 ≤ Q ≤ 105).
The following Q Q Q lines describe queries. The i i i-th of these lines contains four space separated integers a i , b i , c i , d i a_i, b_i, c_i, d_i ai,bi,ci,di. These represent the i i i-th query: is it possible to create T [ c i . . d i ] T[ci..di] T[ci..di] from S [ a i . . b i ] S[ai..bi] S[ai..bi] by applying the above transitions finite amount of times?
Here, U [ x . . y ] U[x..y] U[x..y] is a substring of U U U that begins at index x x x (indexed from 1 1 1) and ends at index y y y. In particular, U [ 1.. ∣ U ∣ ] U[1..|U|] U[1..∣U∣] is the whole string U U U.
It is guaranteed that 1 ≤ a ≤ b ≤ ∣ S ∣ 1 ≤ a ≤ b ≤ |S| 1 ≤ a ≤ b ≤ ∣S∣ and 1 ≤ c ≤ d ≤ ∣ T ∣ 1 ≤ c ≤ d ≤ |T| 1 ≤ c ≤ d ≤ ∣T∣.
Print a string of Q Q Q characters, where the i i i-th character is ′ 1 ′ '1' ′1′ if the answer to the i i i-th query is positive, and ′ 0 ′ '0' ′0′ otherwise.
Input
AABCCBAAB
ABCB
5
1 3 1 2
2 2 2 4
7 9 1 1
3 4 2 3
4 5 1 3
Output
10011
Note
In the first query we can achieve the result, for instance, by using transitions .
The third query asks for changing A A B AAB AAB to A A A — but in this case we are not able to get rid of the character ′ B ′ 'B' ′B′.
题意:
给定字符变换规则:
A -> BC
B -> AC
C -> AB
AAA -> 空
给定两个长度为10万以内的字符串 S S S和 T T T,只有ABC三种字符。
一共有 q ( q < = 1 0 5 ) q(q<=10^5) q(q<=105)组询问,每次询问 a , b , c , d a,b,c,d a,b,c,d
问字符串子串 S [ a , b ] S[a,b] S[a,b]是否能通过若干次字符变换变成 T [ c , d ] T[c,d] T[c,d]
题解:
首先我们可以知道
B <-> C
那么我们可以先将 A A A看作 1 1 1, B B B/ C C C看作 0 0 0,然后将S串和T串都转换成01串。
我们发现,无论每个 0 0 0前面有几个 1 1 1,这些 1 1 1都是可以被消除的;而且每个 1 1 1可以变成 2 ∗ k ( k > = 1 ) 2*k(k>=1) 2∗k(k>=1)个 0 0 0。
我们现在只需要考虑两个子串内的 0 0 0的个数和后缀的 1 1 1的个数即可,对于 0 0 0的个数差值为奇数的情况或者S串中0的个数大于T串中0的个数的情况,这些是不能转换的,对于结尾的连续的1的长度大于第二个串的情况,如果差值是3的倍数,那么刚好可以转换,否则的话需要判断0的差值是否大于等于2且为偶数。注意特判一下 S [ a , b ] S[a,b] S[a,b]是全 1 1 1串的情况。
#include
#define LiangJiaJun main
#define ll long long
using namespace std;
char s[2][100004],ans[100004];
int sum[2][100004],l[2];
int calc(int pt,int l,int r){
return sum[pt][r]-sum[pt][l-1];
}
int getcon(int pt,int a,int b){
int l=a,r=b,mid,ans=b+1;
while(l<=r){
mid=(l+r)>>1;
if(calc(pt,mid,b)==b-mid+1){
ans=mid;
r=mid-1;
}
else l=mid+1;
}
return b-ans+1;
}
bool check(int a,int b,int c,int d){
int g01=getcon(0,a,b),g11=getcon(1,c,d);
int g00=b-a+1-calc(0,a,b),g10=d-c+1-calc(1,c,d);
if(g01<g11||g00>g10)return 0;
int delta=g01-g11;
int gp=(delta%3>0);
int sub=g10-g00;
if(sub<(gp<<1))return 0;
if(sub&1)return 0;
if(g01==b-a+1&&sub>0&&g01==g11)return 0;
return 1;
}
int LiangJiaJun(){
scanf("%s",s[0]+1);
scanf("%s",s[1]+1);
l[0]=strlen(s[0]+1);
l[1]=strlen(s[1]+1);
sum[0][0]=0;
sum[1][0]=0;
for(int i=0;i<=1;i++){
for(int j=1;j<=l[i];j++){
sum[i][j]=sum[i][j-1]+(s[i][j]=='A');
}
}
int q,len=0;scanf("%d",&q);
for(int i=1;i<=q;i++){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
ans[i]=check(a,b,c,d)?'1':'0';
}
ans[q+1]='\n';
puts(ans+1);
return 0;
}