Segment Occurrences CodeForces - 1016B(KMP)

给你两个由小写英文字母组成字符串s,t。如果s[i...i+|t|-1] = t (|t|表示t的长度),则认为s[i...i+|t|-1] 是t的相等串。现在有q次询问,每次询问你s[L..R]中有多少个不同位置的t的相等串。

Input

第一行输入三个整数n,m,q,表示s,t的长度和询问次数。(1 <= n,m <= 1000 , 1 <= q <= 1000000)。

第二三行分别给出s,t。

接下来q行,每行输入L,R,表示所要查询的区间。(1 <= L <= R <= n)

Output

输出q行,表示每次查询的结果。

Examples

Input1

10 3 4
codezzzces
zzz
1 3
3 10
5 6
5 7

Output1

0
1
0
1

Input2

15 2 3
abacabadabacaba
ba
1 15
3 4
2 14

Output2

4
0
3

Input3

3 5 2
aaa
baaab
1 3
1 1

Output3

0
0

这道题目,可以使用KMP来做,也可以使用STL来做。

1.STL 解法

就是我先将第二个字符串 在第一个字符串的位置都找出来存到一个数组中去,然后在一堆询问中,遍历数组去找一共出现了几次,时间相比KMP要少很多。但是 有一些KMP的题目 是不适合使用 STL 去FIND的,很有可能会超时,有的题目使用STL 就会更高效 简单。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<vector>
#include<string.h>
#include<bits/stdc++.h>
const int maxn=1000005;
using namespace std;

int main()
{
	std::ios::sync_with_stdio(false);
	
	vector<int>ans;
	string s,t;
	int len;
	int len2;
	int q;
	cin>>len>>len2>>q;
	cin>>s>>t;
	
	size_t found=s.find(t);
	while(found!=string::npos)
	{
		ans.push_back(found+1);
		found=s.find(t,found+1);
	}
	int l,r;
	while(q--)
	{
		int k=0;
		cin>>l>>r;
		if(r-l+1>=len2)
		for(int i=0;i<ans.size();i++)
		{
			if(l<=ans[i]&&r>=ans[i]+len2-1)
				k++;
				
		}
		
		cout<<k<<endl;
	}
	return 0;
}

2.KMP

怎么感觉 KMP 写的比STL 简单许多,但是时间 时间上STL快一些

就是将KMP 匹配范围更新为 题目所给的 l,r,我们在这段区域内匹配字符串 就可以了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<vector>
#include<string.h>
#include<bits/stdc++.h>
const int maxn=1000005;
using namespace std;
int len1,len2,q;

string s,t;
int nex[maxn];
void getnex(string t)
{
	int i=0;
	int j=-1;
	nex[0]=-1;
	while(i<len2)
	{
		if(j==-1||t[i]==t[j])
		{
			i++;
			j++;
			nex[i]=j;
		}
		else
			j=nex[j];
		
	}
}

int kmp(int l,int r)
{
	int k=0;

	int i=l-1;
	int j=0;
	
	while(i<r)
	{
		if(j==-1||s[i]==t[j])
		{
			i++;
			j++;
		}
		else
			j=nex[j];
		if(j>=len2)
		{
			k++;
			j=nex[j];	
		}		
	}
	return k;
}



int main()
{
	std::ios::sync_with_stdio(false);
	cin>>len1>>len2>>q>>s>>t;
	getnex(t);
	while(q--)
	{
		int l,r;
		cin>>l>>r;
		cout<<kmp(l,r)<<endl;
	}
	return 0;
}

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89414310