$KMP$。

$n=1$和$n=2$的时候可以单独计算。$n>2$时,可以拿字符和数字分别做一次匹配,然后扫描一遍判断一下就可以计算出答案了。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c=getchar(); x=;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) {x=x*+c-''; c=getchar();}
} const int maxn=;
struct X { LL num; int a; }s[maxn],t[maxn];
int lens,lent,n,m;
char op[];
int nx[maxn],f[maxn],g[maxn];
LL a[maxn],b[maxn]; int len1,len2; void get_next()
{
int j=-,i=; nx[]=-;
while(i<len2)
{
if(j==-||b[i]==b[j]) i++, j++, nx[i]=j;
else j=nx[j];
}
} void kmp(bool x){
get_next();
int i=,j=;
while(i<len1){
if(j==-||a[i]==b[j]) i++ ,j++;
else j=nx[j];
if(j==len2)
{
if(x==) f[i-j+len2]=;
else g[i-j+len2]=;
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",op); int L=strlen(op);
int num=,sign;
for(int j=;j<=L-;j++) num=num*+op[j]-'';
sign=op[L-]-'a'+;
if(lens==||sign!=s[lens-].a) { s[lens].num=num; s[lens].a=sign; lens++; }
else s[lens-].num+=num;
} for(int i=;i<=m;i++)
{
scanf("%s",op); int L=strlen(op);
int num=,sign;
for(int j=;j<=L-;j++) num=num*+op[j]-'';
sign=op[L-]-'a'+;
if(lent==||sign!=t[lent-].a) { t[lent].num=num; t[lent].a=sign; lent++; }
else t[lent-].num+=num;
} if(lent==)
{
LL ans=;
for(int i=;i<lens;i++)
{
if(s[i].a!=t[].a) continue;
if(s[i].num<t[].num) continue;
ans=ans+s[i].num-t[].num+;
}
printf("%lld\n",ans);
}
else if(lent==)
{
LL ans=;
for(int i=;i<lens-;i++)
{
if(s[i].a!=t[].a||s[i+].a!=t[].a) continue;
if(t[].num>s[i].num||t[].num>s[i+].num) continue;
ans++;
}
printf("%lld\n",ans);
}
else
{
for(int i=;i<lens;i++) a[i]=s[i].a;
for(int i=;i<lent;i++) b[i]=t[i].a;
len1=lens,len2=lent; kmp(); memset(a,,sizeof a); memset(b,,sizeof b);
for(int i=;i<lens;i++) a[i]=s[i].num;
for(int i=;i<lent-;i++) b[i-]=t[i].num;
len1=lens; len2=lent-; kmp(); LL ans=;
for(int i=;i<lens;i++)
{
if(f[i+]==) continue;
if(g[i]==) continue;
if(s[i].num<t[lent-].num) continue;
if(s[i-lent+].num<t[].num) continue;
ans++;
}
printf("%lld\n",ans); }
return ;
}

CodeForces 631D Messenger的更多相关文章

  1. codeforces 631D. Messenger kmp

    题目链接 首先想到kmp, 和普通的不一样的是,中间部分严格相等, 头和尾的字符相等但是数量可以不相等. 所以应该把子串的头和尾先去掉,然后对剩下的部分进行kmp. 子串长度为1或2要特别讨论. 不要 ...

  2. Codeforces 631D Messenger【KMP】

    题意: 给定由字符串块(字符及连续出现的个数)组成的字符串t,s,求t串中有多少个s. 分析: KMP 这题唯一需要思考的地方就是如何处理字符串块.第一想到是把他们都展开然后进行KMP,可是展开后实在 ...

  3. CodeForces 631D Messenger —— (kmp的应用)

    这题是一个kmp的应用,思路是有,但是代码实现能力太弱,细节考虑不全,敲了很长时间才AC.. 题意:字符串用如下的方法表示,例如aaabbbbcc表示为3-a,4-b,2-c.那么问t串在s串中出现了 ...

  4. 【18.40%】【codeforces 631D】Messenger

    time limit per test 2 seconds memory limit per test 512 megabytes input standard input output standa ...

  5. codeforces 1288E. Messenger Simulator(树状数组)

    链接:https://codeforces.com/contest/1288/problem/E 题意:序列p的长度为n,初始序列为1 2 3 4 ...n,然后有m次操作,每次指定序列中一个数移动到 ...

  6. 631D Messenger

    题目大意 给你串s和t 但是每个串都被表示为多个二元组(x,y)表示字符x连续出现y次 问t在s中出现了多少次 分析 我们先将s和t每个串中二元组合并 即相邻两个二元组如果字符相等则将它们变为一个 特 ...

  7. Codeforces Round #344 (Div. 2) D. Messenger kmp

    D. Messenger 题目连接: http://www.codeforces.com/contest/631/problem/D Description Each employee of the ...

  8. Codeforces Round #344 (Div. 2) D. Messenger (KMP)

    D. Messenger time limit per test2 seconds memory limit per test512 megabytes inputstandard input out ...

  9. Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator

    可以推出 min[i]要么是i要么是1,当a序列中存在这个数是1 max[i]的话就比较麻烦了 首先对于i来说,如果还没有被提到第一位的话,他的max可由他后面的这部分序列中 j>=i 的不同数 ...

随机推荐

  1. CSS3的应用,你学会了吗?

    开场白 CSS3相对于CSS2引入了很多的新的css属性和特效,利用css3实现了原来需要加入js才能模拟的效果,因此前端性能提高了很多. 各大浏览器厂商包括IE都逐渐的加大对CSS3 HTML5的支 ...

  2. javascript脚本化文档

    1.getElememtById /** * 获取指定id的的元素数组 */ function getElements(/*ids...*/) { var elements = {}; for(var ...

  3. 微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件

    原文:微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件 开篇介绍 大多数情况下我们的 SSIS 包都会配置在 SQL Agent ...

  4. 查询select

    --------------select查询-------------------查询所有信息(方法一)select * from stuinfo --*号代表所有列--查询所有信息(方法二)sele ...

  5. ios中mvc的FormsAuthentication.SetAuthCookie(cookieUserName, false)失败

    如果楼主使用.net开发,要注意FormsAuthentication.SetAuthCookie 方法的使用会导致ios出现该问题.因为这个方法在ios设备上是把票据加入到url中,导致url和你的 ...

  6. 《剑指Offer》面试题-二维数组中的查找

    题目1384:二维数组中的查找 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7318 解决:1418 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到 ...

  7. 写入与导出excel

    检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 HRE ...

  8. WCF基于MSMQ的事件代理服务

    前言 公司目前楼主负责的项目正在改版升级,对之前的服务也在作调整,项目里有个操作日志的模块,就决定把日志单独提取出来,做个日志服务,所以就有了这篇文章 正文 MSMQ作为消息队列,B/S项目调用日志服 ...

  9. windows下使用git时生成sshkey和配置

    在windows下如何安装git就不介绍了,我这里主要使用的TortoiseGit,主要记录下在windows上如何通过sshkey链接git 在开始菜单中找到git bash,git bash是gi ...

  10. 【又长见识了】C#异常处理,try、catch、finally、throw

    异常处理:程序在运行过程中,发生错误会导致程序退出,这种错误,就叫做异常.处理这种错误,就叫做异常处理. 1.轻描淡写Try.Catch.Finally.throw用法 在异常处理中,首先需要对可能发 ...