[codeforces923D]Picking Strings

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.

Input

The first line contains a string S ( 1   ≤   ∣ S ∣   ≤   1 0 5 ) S (1 ≤ |S| ≤ 10^5) S(1S105). The second line contains a string T ( 1   ≤   ∣ T ∣   ≤   1 0 5 ) T (1 ≤ |T| ≤ 10^5) T(1T105), 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(1Q105).

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| 1abS and 1   ≤   c   ≤   d   ≤   ∣ T ∣ 1 ≤ c ≤ d ≤ |T| 1cdT.

Output

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.

Example

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 &lt; = 1 0 5 ) q(q&lt;=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 &gt; = 1 ) 2*k(k&gt;=1) 2kk>=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<bits/stdc++.h>
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值