Gym - 101741K Consistent Occurrences

本文介绍了一种优化的字符串匹配算法,通过预处理和哈希值计算来提高查询效率。该方法利用了字符串的本质不同长度特性,针对每个起点预处理哈希值,并使用Map存储答案,实现了高效查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标签:根号算法

题目

题目传送门

Let us define a consistent set of occurrences of string t in string s as a set of occurrences of t in s such that no two occurrences intersect (in other words, no character position in s belongs to two different occurrences).

You are given a string s consisting of n lowercase English letters, and m queries. Each query contains a single string ti.

For each query, print the maximum size of a consistent set of occurrences of t in s.

Input

The first line contains two space-separated integers n and m: the length of string s and the number of queries (1 ≤ n ≤ 105, 1 ≤ m ≤ 105).

The second line contains the string s consisting of n lowercase English letters.

Each of the next m lines contains a single string ti consisting of lowercase English letters: the i-th query (1 ≤ |ti| ≤ n, where |ti| is the length of the string ti).

It is guaranteed that the total length of all ti does not exceed 105 characters.

Output

For each query i, print one integer on a separate line: the maximum size of a consistent set of occurrences of ti in s.

Example

Input

6 4
aaaaaa
a
aa
aaa
aaaa

Output

6
3
2
1

分析

显然,对于一个字符串S,考虑其中本质不同的长度只有 m m 个,所以我们对每个起点预处理出 m m 个hash值,然后将答案存入Map

之后对每个询问,排序后直接计算hash查询就好了

时间复杂度 O(nn) O ( n n )

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
inline ll read(){
    ll f=1,x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//**********head by yjjr**********
#define pa pair <int,int>
#define mp make_pair
#define fi first
#define se second
const int maxn=1e5+6;
const int bas[2]={11257,12257};
const int Mod[2]={1e9+7,1e9+9};
int n,m,all,cur,l[maxn],r[maxn],ans[maxn],len[maxn],h[2][maxn],pwd[2][maxn];
map<pa,pa>cnt;
char s[maxn],t[maxn]; 
inline void solve(int len){
    cnt.clear();
    rep(i,len,n){
        pa val=mp((h[0][i]-1ll*h[0][i-len]*pwd[0][len]%Mod[0]+Mod[0])%Mod[0],(h[1][i]-1ll*h[1][i-len]*pwd[1][len]%Mod[1]+Mod[1])%Mod[1]);
        if(cnt.find(val)==cnt.end())cnt[val]=mp(1,i);
        else if(i-cnt[val].se<len)continue;else ++cnt[val].fi,cnt[val].se=i;
    }
    rep(i,1,m)
        if(r[i]-l[i]+1==len){
            pa cur=mp(0,0);
            rep(j,l[i],r[i])cur=mp((1ll*cur.fi*bas[0]+t[j])%Mod[0],(1ll*cur.se*bas[1]+t[j])%Mod[1]);
            ans[i]=cnt[cur].fi;
        }
}
int main(){
    n=read(),m=read();
    scanf("%s",s+1);
    pwd[0][0]=pwd[1][0]=1;
    rep(j,0,1)
        rep(i,1,n){
            h[j][i]=(1ll*h[j][i-1]*bas[j]+s[i])%Mod[j];
            pwd[j][i]=1ll*pwd[j][i-1]*bas[j]%Mod[j];
        }
    rep(i,1,m){
        scanf("%s",t+cur+1);
        l[i]=cur+1,len[i]=strlen(t+cur+1);
        cur+=len[i],r[i]=cur;
    }
    sort(len+1,len+1+m),all=unique(len+1,len+1+m)-len-1;
    rep(i,1,all)solve(len[i]);
    rep(i,1,m)printf("%d\n",ans[i]);
    return 0;
}
编程竞赛和算法训练平台如 Codeforces Gym 提供了大量高质量的竞赛题目,供选手进行训练和提升。关于 Gym 103409K 问题的解决方案或讨论,通常可以通过以下几种方式获取相关信息: 1. **Codeforces Gym 页面**:Gym 103409K 问题属于某个特定的比赛或训练集,可以在 Codeforces 的 Gym 页面中查找该问题编号的对应比赛,并查看题目描述、提交记录以及可能存在的公开讨论[^1]。 2. **提交记录与代码查看**:在 Codeforces 平台上,用户可以提交代码后查看其他人的提交记录,包括通过的代码。通过阅读其他选手的代码,可以学习不同的解题思路和优化技巧。通常在问题页面中点击“Standings”可以查看排名,并通过“Hacks”或“Submissions”查看具体代码[^1]。 3. **官方题解与讨论区**:某些比赛会提供官方题解(Editorial),通常在比赛结束后发布。如果该比赛有官方题解,可以在 Codeforces 的博客(Blog)部分查找相关文章。此外,问题页面下方的评论区也可能包含选手之间的讨论,有时会涉及解题思路或技巧[^1]。 4. **社区资源**:一些编程竞赛社区如 Codeforces、AtCoder、Topcoder 的论坛,以及 Stack Overflow、Reddit 的 r/learnprogramming 或 r/programming 等板块,也可能存在对该问题的讨论。 5. **GitHub 仓库**:许多参赛者会将自己的解题代码整理到 GitHub 上,搜索关键词 "Gym 103409K solution" 或类似内容,可能会找到相关代码或题解。 ### 示例代码结构 以下是一个用于处理典型算法竞赛问题的 Python 模板示例,适用于读取输入并输出结果: ```python def main(): import sys input = sys.stdin.read data = input().split() # 示例处理逻辑 n = int(data[0]) a = list(map(int, data[1:n+1])) # 示例输出 print(sum(a)) if __name__ == "__main__": main() ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值