子串查询

题目描述
给出一个长度为n的字符串s和q个查询。对于每一个查询,会输入一个字符串t,你需要判断这个字符串t是不是s的子串。子串的定义就是存在任意下标a<b<c<d<e,那么”s[a]s[b]s[c]s[d]s[e]”就构成s的一个子串。如”abc”的子串有”a”、”b”、”c”、”ab”、”ac”、”bc”、”abc”。
输入描述:
第一行两个数n,q。1<=n,q<=1e5。

第二行一个长度为n的字符串s,所有字符都为小写拉丁字符。

接下来q行每行一个字符串t。1<=|t|<=50。
输出描述:
对于每个查询,如果t是s的字串,输出”YES”,否则输出”NO”。每个答案占一行。
示例1
输入
复制

8 4
ababcbaa
abac
accb
aaaa
abcba
输出
复制

YES
NO
YES
YES


建立字母前缀和,然后二分第一次的位置即可。


#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,q,cnt[N][30],num[30];
char str[N],op[50];
int bsearch(int l,int r,char x,int k){
	while(l<r){
		int mid=l+r+1>>1;
		if(cnt[mid][x-'a']>=k)	l=mid;
		else	r=mid-1;
	}
	return l;
}
signed main(){
	scanf("%d %d %s",&n,&q,str+1);
	for(int i=n;i>=0;i--){
		for(int j=0;j<26;j++)	cnt[i][j]=num[j];//每个字母后的每个字母个数 
		if(i)	num[str[i]-'a']++;
	}
	while(q--){
		scanf("%s",op+1);	int flag=0;	int len=strlen(op+1);	int x=0;
		for(int i=1;i<=len;i++){
			if(!cnt[x][op[i]-'a']){
				flag++;	break;
			}
			x=bsearch(x,n,op[i],cnt[x][op[i]-'a'])+1;
		}
		puts(flag?"NO":"YES");
	} 
	return 0;
}
全部评论

相关推荐

家人们,我现在真的好纠结。我是26届的,目前还没有实习过。我现在的情况是,想参加秋招,但是感觉自己的简历特别空,没有实习经历会不会秋招直接凉凉啊?可我又听说现在很多公司对26届实习生也不太感冒,说什么不确定性大。而且我最近在准备考公,时间上也有点冲突。要是把时间花在实习上,备考时间就少了。但要是不实习,又怕以后就业有问题😫有没有懂行的友友帮我分析分析:26届现在不实习,秋招找工作真的会很难吗?考公和实习该怎么平衡啊?如果现在不实习,考完公再去找实习还来得及吗?真的太焦虑了,希望大家能给我点建议🙏
小破站_程序员YT:我可能和大家的观点不一样。人的精力是有限的,不能既要还要。你又想实习又想考公最后又要秋招上岸,我觉得哪有那么多的选择。你如果想考上岸,那就全力以赴。如果想秋招上岸,就继续投实习,投没了,就继续准备秋招,秋招不行继续春招。别到最后,考公没上岸,觉得是花了时间浪费在找实习上了, 秋招没上岸,觉得是浪费时间准备考公去了。我是认为很难说可以去平衡 不喜勿喷,可以叫我删除
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务