Codeforces Round #470 E Perpetual Subtraction

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lfhase/article/details/79593369

题目链接:点击打开链接

题意:给定两个由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;
}

猜你喜欢

转载自blog.csdn.net/Lfhase/article/details/79593369