GYM103371B Cilantro 题解

有一个经典的小trick,就是说如果两个序列的\(0\)\(1\)的个数分别相等,那么第一个序列可以通过调整入栈顺序完美和第二个匹配,然后我们用第一个串的前半部分去匹配第二个串的后半部分,具体见代码。(相当于如果说\([1,p]\)可以通过\([p1,n]\)调整使得它可以和\([p2,n]\)匹配,那么用\(p+1\)去尝试匹配剩余的点一定可以相互匹配成功。)

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e6+10;
int n,suma[maxn],sumb[maxn],p,p1,p2,l1,l2;
long long ans;
char a[maxn],b[maxn];
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>(a+1)>>(b+1);
	for(int i=1;i<=n;i++){
		suma[i]=suma[i-1]+(a[i]=='Y');
		sumb[i]=sumb[i-1]+(b[i]=='Y');
	}
	if(suma[n]!=sumb[n]){
		cout<<0;
		return 0;
	}
	p=1;
	p1=n;
	p2=n;
	while(p2>1){
		if(a[p]==b[p2]){
			p++;
			p2--;
			continue;
		}
		l1=p1;
		l2=p2;
		while(p1&&p2){
			p1--;
			p2--;
			if(suma[l1]-suma[p1]==sumb[l2]-sumb[p2]){
				break;
			}
		}
	}
	for(int i=1;i<=p;i++){
		if(a[i]==b[1]){
			ans+=i;
		}
	}
	cout<<ans;
	return 0;
}
posted @ 2025-05-15 16:21  特别之处  阅读(5)  评论(0)    收藏  举报