给定 和两个长 的 串 与 。
设入栈序列为 ,出栈序列为 的所有栈操作序列中, 可能对应的 中的下标集合为 。
求 。
例如 , 时答案为 ,因为共有 种栈操作序列满足入栈序列为 ,出栈序列为 :
- 进,进,进,出,出,出,此时 来自 ;
- 进,进,出,进,出,出,此时 来自 ;
所以答案为 。
。
首先有个结论,对于任意两个 的个数相等且 的个数相等的 序列 与 ,总有合法的栈操作序列满足入栈序列为 且出栈序列为 。
证明十分简单,考虑贪心,从左往右逐位考虑 ,设当前出栈序列已经匹配 个,则若栈顶元素 且 则 入栈, 否则 。这样栈中不会同时出现两种不同元素,一定可以构造出来。
考虑从 开始,逐个确定 是否有可能去到 。先不考虑 的情况,那么若 去了 ,则 出栈时 一定都在栈中。
所以可以找到 且 中 的个数等于 中 的个数的最大的 ,令 ;找不到则 ,求出 后可以这样构造:

那么显然答案即为 ,问题变成求解 ,双指针即可,时间复杂度 。
代码如下:
// Problem: B. Cilantro
// Contest: XXII Open Cup, Grand Prix of Korea
// URL: https://codeforces.com/gym/103371/problem/B
// Memory Limit: 1024 MB
// Time Limit: 500 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
using namespace std;
const int S=5000005;
int n;
char a[S],b[S];
int sa[S],sb[S];
int pos[S];
int main()
{
scanf("%d",&n);
scanf("%s%s",a+1,b+1);
for(int i=1;i<=n;i++) sa[i]=sa[i-1]+(a[i]=='Y'),sb[i]=sb[i-1]+(b[i]=='Y');
for(int i=1,r=n;i<=n;i++)
{
while(r>=i&&sa[r]-sa[i-1]!=sb[r-i+1]) r--;
pos[i]=r;
}
long long ans=0;
for(int i=1;i<=n;i++) if(pos[i]>=i&&a[i]==b[1]) ans+=i;
printf("%lld\n",ans);
return 0;
}