題目鏈接:https://codeforces.com/contest/947/problem/D
題意:給定兩個由A、B、C三個字母組成的串S、T,以及一系列串上的操作,給出Q的詢問,詢問S[ a, b]可否經過一系列操作生成T[ c, d]。
思路:根據數據規模,必須要離線構建一些東西來解決該問題。
首先,觀察給出的操作,可以發現如下規律:
1. C和B可以相互轉化
2. B之前的A可以任意增添
3. B只能增加,且B的每次增加都爲偶數
所以,不妨根據前後兩串中B的數量進行分類討論:
1. 若第一個串內B的數量大於第二串,則必然不行。
2. 若兩者相等,則判斷所有B之後A的數量,若前者的這樣的A的數量 - 後者 是3的倍數則可行,否則不可行。
3. 若前者小於後者,先判斷差是否爲偶數,若不是偶數則不可行。如果是偶數,則判斷所有B之後A的數量,若前者大於後者且差不爲0則必然可行,若兩者這樣的A的數量相等,且前者B的數量不爲0則可行,否則不可行。
剩下的工作即計算B的數量以及這樣的A的數量,看代碼即可。
AC代碼如下:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;
string S, T;
int cnts[MAXN];
int cntgs[MAXN];
int cntt[MAXN];
int cntgt[MAXN];
int Q;
int main()
{
FSIO;
cin>>S>>T;
for(int i=0;i<S.length();++i)
if(S[i]=='B'||S[i]=='C') cnts[i+1]=cnts[i]+1;
else cnts[i+1]=cnts[i], cntgs[i+1] = cntgs[i]+1;
for(int i=0;i<T.length();++i)
if(T[i]=='B'||T[i]=='C') cntt[i+1]=cntt[i]+1;
else cntt[i+1]=cntt[i], cntgt[i+1] = cntgt[i]+1;
/*for(int i=1;i<=S.length();++i) cout<<cnts[i]<<" ";
cout<<endl;
for(int i=1;i<=T.length();++i) cout<<cntt[i]<<" ";
cout<<endl;*/
cin>>Q;
int l1, l2, r1, r2;
for(int i=1;i<=Q;++i)
{
cin>>l1>>r1>>l2>>r2;
if((cnts[r1]-cnts[l1-1])>(cntt[r2]-cntt[l2-1])) cout<<0;
else if((cnts[r1]-cnts[l1-1])==(cntt[r2]-cntt[l2-1]))
{
int tmp = min(cntgs[r1], r1-l1+1);
int tmp2 = min(cntgt[r2], r2-l2+1);
if(tmp>=tmp2&&(tmp-tmp2)%3==0) cout<<1;
else cout<<0;
}
else
{
int cntb = cntt[r2]-cntt[l2-1]-(cnts[r1]-cnts[l1-1]);
if(cntb%2==0)
{
int tmp = min(cntgs[r1], r1-l1+1);
int tmp2 = min(cntgt[r2], r2-l2+1);
if(tmp>tmp2||(tmp==tmp2&&(cnts[r1]-cnts[l1-1]))) cout<<1;
else cout<<0;
}
else cout<<0;
}
}
cout<<endl;
return 0;
}