Codeforces 631D - Messenger KMP
来源:互联网 发布:装修手机设计软件 编辑:程序博客网 时间:2024/06/05 20:15
题目:http://codeforces.com/problemset/problem/631/D
题意:
输入一段压缩后的字符串,问子串在主串中出现的次数
分析:
KMP匹配求子串在主串中出现的次数,因为是压缩后的字符串,这就要考虑字符串的长度。因为要完全匹配,显然,模式串的中间的字符和数目必须要完全和主串匹配,但是前后两个字符数目可以不相等,所以模式串删去前后两个字符,去和主串匹配,完全匹配时,在比较前后两个字符是否主串中相应位置的字符匹配。删去前后两个字符前,要判断模式串长度:
如果模式串长度是1,那么直接在主串中找对应的字符,比较长度,如果模式串长度是2,那么也是直接在主串中找模式串,比较字符一样,并且主串中字符数目均不小于模式串中字符数目。然后剩下的就用KMP匹配就好。
#include<iostream>#include<cstdio>using namespace std;#define fi first#define se second#define mp make_pairtypedef long long ll;typedef pair<char,ll>pii;const int N=2e5+5;pii s[N],t[N],t0,tt;int next[N],tlen,slen;void getNext(){ int i,j; i=0;j=next[0]=-1; while(i<tlen){ if(j==-1||t[i]==t[j])next[++i]=++j; else j=next[j]; }}ll KMP_Count(){ ll ans=0; getNext(); int j=0; for(int i=1;i<slen;i++){ while(j>0&&s[i]!=t[j])j=next[j]; if(s[i]==t[j])j++; if(j==tlen){ if(t0.fi==s[i-tlen].fi&&t0.se<=s[i-tlen].se &&tt.fi==s[i+1].fi&&tt.se<=s[i+1].se)ans++; j=next[j]; } } return ans;}int main(){ int n,m; //freopen("f.txt","r",stdin); scanf("%d%d",&n,&m); char ci; ll li; scanf("%I64d-%c",&s[0].se,&s[0].fi); n--; slen=1; while(n--){ scanf("%I64d-%c",&li,&ci); if(s[slen-1].fi==ci){ s[slen-1].se+=li; } else s[slen++]=mp(ci,li); } scanf("%I64d-%c",&t[0].se,&t[0].fi); //cout<<t[0].fi<<' '<<t[0].se<<endl; m--; tlen=1; while(m--){ scanf("%I64d-%c",&li,&ci); if(t[tlen-1].fi==ci){ t[tlen-1].se+=li; } else t[tlen++]=mp(ci,li); } if(tlen==1){ ll ans=0; for(int i=0;i<slen;i++){ if(t[0].fi==s[i].fi&&t[0].se<=s[i].se)ans+=s[i].se-t[0].se+1; } cout<<ans<<endl;return 0; } if(tlen==2){ ll ans=0; for(int i=1;i<slen;i++){ if(t[0].fi==s[i-1].fi&&t[1].fi==s[i].fi &&t[0].se<=s[i-1].se&&t[1].se<=s[i].se){ ans++; } } cout<<ans<<endl;return 0; } t0=t[0];tt=t[tlen-1]; for(int i=0;i<tlen-1;i++) t[i]=t[i+1]; tlen-=2; cout<<KMP_Count()<<endl; return 0;}
Input
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 200 000) — the number of blocks in the strings t and s, respectively.
The second line contains the descriptions of n parts of string t in the format “li-ci” (1 ≤ li ≤ 1 000 000) — the length of the i-th part and the corresponding lowercase English letter.
The second line contains the descriptions of m parts of string s in the format “li-ci” (1 ≤ li ≤ 1 000 000) — the length of the i-th part and the corresponding lowercase English letter.
Output
Print a single integer — the number of occurrences of s in t.
Examples
Input
5 3
3-a 2-b 4-c 3-a 2-c
2-a 2-b 1-c
Output
1
- Codeforces 631D:Messenger KMP
- Codeforces 631D Messenger【KMP】
- Codeforces 631D - Messenger KMP
- [KMP] Codeforces #631D. Messenger
- 【18.40%】【codeforces 631D】Messenger
- Codeforces Round #344 (Div. 2) D. Messenger(kmp)
- Codeforces Round #344 (Div. 2)D. Messenger【kmp】
- Codeforces Round #344 (Div. 2) D. Messenger(kmp,细节)
- Codeforces Round #344 (Div. 2) D. Messenger (KMP)
- Codeforces Round #344 (Div. 2) D. Messenger
- Codeforces Round #344 (Div. 2) D. Messenger
- codeforces 182D KMP+math
- Codeforces Round #344 (Div. 2) D. Messenger CF631D
- codeforces 93 div2 D题 - kmp- 3
- codeforces D. Common Divisors kmp基础
- codeforces 182D Common Divisors KMP做法
- codeforces #299 div2 D(Kmp || hash)
- Codeforces Round #269 (Div. 2) D kmp
- HTML+CSS基础(1)-理解什么是HTML和CSS
- css的外边距合并(如何实现不合并)
- leetcode 92. Reverse Linked List II
- 开发工具带来的进度影响
- Web后端语言模拟http请求(带用户名和密码)实例代码大全
- Codeforces 631D - Messenger KMP
- 安卓开发小知识-AppWidget探索
- Java基础之六:关键字this、super、static
- 神经网络可以拟合任意函数的视觉证明A visual proof that neural nets can compute any function
- 华为2014年校园招聘机试题(2)
- vim下接下Ctrl+S造成程序僵死
- 虚函数和纯虚函数的作用与区别
- Jenkins进阶系列之——17Jenkins升级、迁移和备份
- Terminal Prompt