Codeforces 947 D Picking Strings 题解

题目链接

很恶心的分类讨论题,恶心程度不亚于初学者做Tic tac toe。据说djq交了很多次才过

先观察单独的一个询问,什么样的字符串a才能变换成字符串b。正向做似乎有点困难,我们考虑反向,什么样的b才能变换成a。为了将b变换成a,我们能做的操作是:把BC变成A,把AB变成C,把AC变成B,以及在串中的任意位置插入连续的3个A。对于一个B,如果我们先在它前面插入3个A,再依次进行\(AB \to C,AC \to B,AB \to C\)的操作,就把一个C变成了B。对于C是同理的。这说明B和C是完全可以自由转化的,也就是B和C是等价的,我们可以把输入的两个串里的C全变成B,以后字符串里就只有两个字母,A和B。这样题目就没那么复杂了,操作也只剩下了:\(BB \to A,AB \to B\),以及在任意位置插入3个A。

接下来进行分类讨论:

  1. 发现对于b,无论怎么操作,其中B的数量的奇偶性都不变,且B的数量不会增加。所以如果a和b中B的数量奇偶性不同或者a中的B比b中的多,就一定无解。

  2. 如果a和b都全部由A组成,那么能做的唯一操作就是加3个A。很容易判断有没有解。

  3. a全部由A组成,而b不是。先把b结尾的一段极长的A拿出来,这些A是永远无法被消除的,令这些A有k个。b剩下的部分最短可以缩成1个A,所以a的长度至少是k+1;最长可以无限(因为可以不断加上3个A,再用右侧的B去缩短)。判断a的长度是否在这个区间内即可。

  4. a和b中都有B。令a右侧有k个A,b右侧有p个A。如果k<p显然无解。 否则,先在b的右侧尽量多地添加一些"AAA",这样b的左边部分只需要额外提供0或1或2个A。如果(k-p)%3=0,那么显然有解。否则,如果a和b中B的数量相等就无解,不等则有解,因为可以把b中最靠右的几个B合成若干A。

时间复杂度\(O(n)\)

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back

void fileio()
{
  #ifdef LGS
  freopen("in.txt","r",stdin);
  freopen("out.txt","w",stdout);
  #endif
}
void termin()
{
  #ifdef LGS
  std::cout<<"\n\nPROGRAM TERMINATED";
  #endif
  exit(0);
}

using namespace std;

string s,t,ans;
char c[100010];
int q,sbc[100010],tbc[100010],psbc[100010],ptbc[100010];

int main()
{
  fileio();
  //freopen("always.in","r",stdin);
  //freopen("always.out","w",stdout);

  scanf("%s",c);s=c;scanf("%s",c);t=c;
  int lst=-1;
  rep(i,s.size())
  {
    psbc[i]=lst;
    if(s[i]=='B'||s[i]=='C') lst=i;
  }
  lst=-1;
  rep(i,t.size())
  {
    ptbc[i]=lst;
    if(t[i]=='B'||t[i]=='C') lst=i;
  }
  rep(i,s.size()) sbc[i+1]=sbc[i]+(s[i]=='B'||s[i]=='C' ? 1:0);
  rep(i,t.size()) tbc[i+1]=tbc[i]+(t[i]=='B'||t[i]=='C' ? 1:0);
  cin>>q;
  int l,r,ll,rr;
  rep(qn,q)
  {
    scanf("%d%d%d%d",&l,&r,&ll,&rr);--l;--r;--ll;--rr;
    int tail1,tail2,len1=r-l+1,len2=rr-ll+1;
    if(s[r]!='A') tail1=0;else tail1=min(len1,r-psbc[r]);
    if(t[rr]!='A') tail2=0;else tail2=min(len2,rr-ptbc[rr]);
    int tot1,tot2;
    tot1=sbc[r+1]-sbc[l];tot2=tbc[rr+1]-tbc[ll];

    // /tuu
    if(tot1%2!=tot2%2||tot1>tot2) ans.pb('0');
    else if(tot1==0&&tot2==0) ans.pb(len2<=len1&&(len1-len2)%3==0 ? '1':'0');
    else if(tot1==0)
    {
      if(tail1<tail2+1) ans.pb('0');
      else ans.pb('1');
    }
    else
    {
      if(tail1<tail2) ans.pb('0');
      else
      {
        LL lft=(tail1-tail2)%3;
        if(lft==0) ans.pb('1');
        else
        {
          if(tot1==tot2) ans.pb('0');
          else ans.pb('1');
        }
      }
    }
  }
  printf("%s\n",ans.c_str());

  termin();
}
posted @ 2022-11-18 16:50  LegendStane  阅读(79)  评论(1)    收藏  举报