[ 雜題 ] Codeforces923D Picking Strings

瞎JB推一下,得到一些結論:

  • BACAABAAACCB\rightarrow AC \rightarrow AAB \rightarrow AAAC \rightarrow C ,反過來也成立,得出 BBCC 是等價的,可以將所有 BB 看成 CC
  • CACAACCC\rightarrow AC \rightarrow AAC \rightarrow C ,也就是說 CC 前面 AA 的個數是可以隨意改變的,那麼只有末尾的 AA 對答案有影響。
  • ACCA\rightarrow CC ,那麼 CC 的個數不能減少,且只能增加 22 的倍數個。

假設 ssCC 的個數爲 aa ,末尾 AA 的個數爲 bbttCC 的個數爲 cc ,末尾 AA 的個數爲 dd
由第 33 個結論得: aacc 必須滿足 aca\le c(ca) mod 2=0(c-a) ~mod ~2 =0
然後分類討論。

  • a=ca=c ,那麼 CC 的個數不能改變,只能把 bb 減少 33 的倍數個。
  • a=0a=0 ,那麼只要判斷是否滿足 b>db>d,因爲我們可以把一個 AA 變成 CCCC ,再去掉前面所有 AA ,使後面 AA 的個數等於 cc
  • 否則,只要判斷是否滿足 bdb\ge d ,理由同上。

所有量都可以 O(n)O(n) 求,再分類討論一下就好啦。

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int k,n,m,Q;
int s1[N],s2[N],f1[N],f2[N];
int l1,r1,l2,r2;
char s[N],t[N];
bool Solve(int l1,int r1,int l2,int r2) {
	int x=s1[r1]-s1[l1-1],y=s2[r2]-s2[l2-1];
	if(x>y||((y-x)&1)) return 0;
	int len1=min(f1[r1],r1-l1+1),len2=min(f2[r2],r2-l2+1);
	if(x==y) {
		if(len1<len2) return 0;
		return !((len1-len2)%3);
	}
	if(!x) return len1>len2;
	return len1>=len2;
}
int main() {
	scanf("%s",s+1);n=strlen(s+1);
	scanf("%s",t+1);m=strlen(t+1);
	for(int i=1;i<=n;i++) s1[i]=s1[i-1]+(s[i]!='A'),f1[i]=s[i]=='A'?f1[i-1]+1:0;
	for(int i=1;i<=m;i++) s2[i]=s2[i-1]+(t[i]!='A'),f2[i]=t[i]=='A'?f2[i-1]+1:0;
	scanf("%d",&Q);
	while(Q--) {
		scanf("%d",&l1);scanf("%d",&r1);scanf("%d",&l2);scanf("%d",&r2);
		putchar(Solve(l1,r1,l2,r2)?'1':'0');
	}
	return 0;
}
發佈了288 篇原創文章 · 獲贊 104 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章