题目大意:求b串在a串中出现多少次。
解题思路:实质是kmp匹配,先把相邻相同的字母合并起来先,a串长度为n,b串的长度为m,匹配的条件是:
当b[1,m-2]与a[i,j]匹配了:
1.判断a[i-1]与b[0]的字母是否一样,而且a[i-1]字母数>=b[0]的字母数。
2.判断a[j+1]与b[m-1]的字母是否一样,而且a[j+1]字母数>=b[m-1]的字母数。
所以,可以看作把b串的头尾去掉后进行匹配,然后再进行头尾的匹配,然后注意
m=1 or 2的情况,特判一下即可。
/* ***********************************************
┆ ┏┓ ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃ ┃ ┆
┆┃ ━ ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃ ┃ ┆
┆┃ ┻ ┃ ┆
┆┗━┓ 马 ┏━┛ ┆
┆ ┃ 勒 ┃ ┆
┆ ┃ 戈 ┗━━━┓ ┆
┆ ┃ 壁 ┣┓┆
┆ ┃ 的草泥马 ┏┛┆
┆ ┗┓┓┏━┳┓┏┛ ┆
┆ ┃┫┫ ┃┫┫ ┆
┆ ┗┻┛ ┗┻┛ ┆
************************************************ */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define rep(i,a,b) for (int i=(a),_ed=(b);i<_ed;i++)
#define per(i,a,b) for (int i=(b)-1,_ed=(a);i>=_ed;i--)
#define inf 0x3f3f3f3f
#define mod 1000000007
#define ll long long
#define ull unsigned long long
const int N = 2e5 + 5;
pair<int,ll>a[N],b[N],c[N];
void Union(pair<int,ll>d[],int &n)
{
int pos=0;
for(int i=1;i<=n;i++)
{
if(pos==0 || d[i].first!=d[pos].first)
{
d[++pos]=d[i];
}
else
d[pos].second+=d[i].second;
}
n=pos;
}
int nex[N],mark[N];
void kmp(int n,int m)
{
for(int i=2;i<m;i++)
{
c[i-1]=b[i];
}
m-=2;
for(int i=1,j=0;i<=m;)
{
if(j==0 || c[j]==c[i])
{
j++,i++;
nex[i]=j;
}
else
j=nex[j];
}
for(int i=1,j=0;i<=n;i++)
{
while (j != 0 && a[i] != c[j + 1])
j = nex[j];
if (c[j + 1] == a[i]) ++j;
if (j == m)
{
mark[i] = 1;
j = nex[j];
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
int x;
char y;
for(int i=1;i<=n;i++)
{
scanf("%d-%c",&x,&y);
a[i]=make_pair(y,x);
}
for(int i=1;i<=m;i++)
{
scanf("%d-%c",&x,&y);
b[i]=make_pair(y,x);
}
Union(a,n);
Union(b,m);
ll ans=0;
if(m==1)
{
for(int i=1;i<=n;i++)
{
if(a[i].first==b[1].first && a[i].second>=b[1].second)
ans += a[i].second - b[1].second + 1;
}
}
else if(m==2)
{
for (int i = 1; i < n; ++i)
{
if (a[i].first == b[1].first && a[i + 1].first == b[2].first &&
a[i].second >= b[1].second && a[i + 1].second >= b[2].second)
ans++;
}
}
else
{
kmp(n,m);
for (int i = 1; i < n; ++i)
{
if (mark[i] && b[1].first == a[i + 1 - m + 1].first && b[1].second <= a[i + 1 - m + 1].second
&&b[m].first == a[i + 1].first && b[m].second <= a[i + 1].second)
ans++;
}
}
cout<<ans<<endl;
return 0;
}