【Codeforces #470 Div. 2 E】Picking Strings

本文探讨了一个字符串转换问题,通过特定的字符转换规则,判断是否能从一个字符串通过有限次操作得到另一个字符串。文章提供了详细的分析思路及C语言实现代码。

problem

outputstandard output
Alice has a string consisting of characters ‘A’, ‘B’ and ‘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| ≤ 105). The second line contains a string T (1 ≤ |T| ≤ 105), each of these strings consists only of uppercase English letters ‘A’, ‘B’ and ‘C’.

The third line contains the number of queries Q (1 ≤ Q ≤ 105).

The following Q lines describe queries. The i-th of these lines contains four space separated integers ai, bi, ci, di. These represent the i-th query: is it possible to create T[ci..di] from S[ai..bi] by applying the above transitions finite amount of times?

Here, U[x..y] is a substring of U that begins at index x (indexed from 1) and ends at index y. In particular, U[1..|U|] is the whole string U.

It is guaranteed that 1 ≤ a ≤ b ≤ |S| and 1 ≤ c ≤ d ≤ |T|.

Output
Print a string of Q characters, where the i-th character is ‘1’ if the answer to the i-th query is positive, and ‘0’ otherwise.

Example
inputCopy
AABCCBAAB
ABCB
5
1 3 1 2
2 2 2 4
7 9 1 1
3 4 2 3
4 5 1 3
outputCopy
10011
Note
In the first query we can achieve the result, for instance, by using transitions .

The third query asks for changing AAB to A — but in this case we are not able to get rid of the character ‘B’.


analysis

  • 大结论题

  • 可以这么想BACAABAAACCB→AC→AAB→AAAC→CCC也同理可以变成B

  • 就是说B,CB,C没有区别可以互换,于是我们把AA看成0,把B,CB,C看成11

  • 接下来要认真考虑各种情况

  • 首先除了末尾连续的0不能消去,字符串中间的任何00我们可以用1凭空变出三个00来消掉

  • 消完后设S串中有S0S000S111T串中有T0T000T111,这些东西用前缀和搞就好了

  • 明显变换过程中,S1只会每次+2+2或者不变,所以S1<T1S1<T1S1T1(mod2)S1≡T1(mod2)才有解,否则无解

  • S0<T0S0<T0无解,因为S0S0要么不变要么每次2−2,不可能变多

  • S1=0T1S1=0≠T1时,如果S0=T0S0=T0无解,因为想变出两个11必须用0

  • S1<T1S1<T1有解,可以把00变成11再变出00来消0,否则还要S0T0(mod3)S0≡T0(mod3)

  • 大概就这样了吧……


code

#include<stdio.h>
#define MAXN 100010
#define min(x,y) (x<y)?(x):(y)

using namespace std;

char st1[MAXN],st2[MAXN];
int a1[MAXN],a2[MAXN],b1[MAXN],b2[MAXN];
int n;

int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

int main()
{
    //freopen("readin.txt","r",stdin);
    scanf("%s%s",st1+1,st2+1);
    for (int i=1;st1[i];i++)
    {
        if (st1[i]=='A')a1[i]=a1[i-1]+1;
        b1[i]=b1[i-1]+(st1[i]!='A');
    }
    for (int i=1;st2[i];i++)
    {
        if (st2[i]=='A')a2[i]=a2[i-1]+1;
        b2[i]=b2[i-1]+(st2[i]!='A');
    }
    n=read();
    while (n--)
    {
        int l1=read(),r1=read(),l2=read(),r2=read(),ok=1;
        int s1=b1[r1]-b1[l1-1],s2=b2[r2]-b2[l2-1];
        int x1=min(r1-l1+1,a1[r1]),x2=min(r2-l2+1,a2[r2]);
        printf("%d",(s1>s2 || (s1+s2)%2==1 || x1<x2 || s1==s2 && x1%3!=x2%3 || s1==0 && x1==x2 && s1!=s2)?0:1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值