$n \leq 100000$的一文本串,给$m \leq 100000$个询问,每次问一小串在文本串的哪一个最短的子串里出现指定次数。注意,询问串互不相同,且总长度$\leq 100000$。

比赛时不会分析复杂度QAQ没想到这么简单

互不相同的询问串,不同的长度会只有根号个。而每个长度的出现次数都是n级别的,因此总的出现次数是$n\sqrt{n}$,只要想出$O(串长+出现次数)$的匹配算法就行了。

然后SA,SAM,AC,bitset挑个写就行了。写了AC。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
#include<set>
//#include<queue>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=; while ((c=getchar())<'' || c>'');
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s;
} //Pay attention to '-' , LL and double of qread!!!! int n,lq;
#define maxn 200011
struct Edge{int to,next;}edge[maxn<<]; int first[maxn],le=;
void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;} set<int> ss[maxn]; int ls=,bel[maxn];
struct AC
{
struct Node{int ch[],fail;}a[maxn];
int num[maxn],size;
AC() {size=; memset(a[].ch,,sizeof(a[].ch));}
int insert(char *s,int id)
{
int now=,m=strlen(s);
for (int i=;i<m;i++)
{
int p=s[i]-'a';
if (!a[now].ch[p])
{
int x=++size;
a[now].ch[p]=x;
}
now=a[now].ch[p];
}
num[id]=now;
return now;
} int que[maxn],head,tail;
void makefail()
{
head=tail=;
for (int i=;i<;i++)
{
int u=a[].ch[i];
if (u) que[tail++]=u,a[u].fail=;
}
while (head!=tail)
{
int x=que[head++];
for (int i=;i<;i++)
{
int u=a[x].ch[i];
if (!u) {a[x].ch[i]=a[a[x].fail].ch[i]; continue;}
que[tail++]=u;
a[u].fail=a[a[x].fail].ch[i];
}
}
}
void buildtree() {for (int i=;i<=size;i++) in(a[i].fail,i);} void pei(char *s)
{
int n=strlen(s),now=;
for (int i=;i<n;i++)
{
now=a[now].ch[s[i]-'a'];
if (!bel[now]) bel[now]=++ls;
ss[bel[now]].insert(i);
}
}
}ac; int ques[maxn],kk[maxn],ll[maxn],ans[maxn]; void bing(int x)
{
int Max=x;
for (int i=first[x];i;i=edge[i].next)
{
Edge &e=edge[i];
bing(e.to);
if (ss[bel[e.to]].size()>ss[bel[Max]].size()) Max=e.to;
} for (int i=first[x];i;i=edge[i].next)
{
Edge &e=edge[i]; if (e.to==Max) continue;
for (auto j=ss[bel[e.to]].begin();j!=ss[bel[e.to]].end();j++) ss[bel[Max]].insert(*j);
}
if (Max!=x)
{
for (auto j=ss[bel[x]].begin();j!=ss[bel[x]].end();j++) ss[bel[Max]].insert(*j);
bel[x]=bel[Max];
} if (ques[x])
{
vector<int> p;
for (auto j=ss[bel[x]].begin();j!=ss[bel[x]].end();j++) p.push_back(*j);
int Ans=0x3f3f3f3f;
for (unsigned int k=kk[ques[x]],j=k-;j<p.size();j++) Ans=min(Ans,p[j]-p[j-k+]);
if (Ans==0x3f3f3f3f) ans[ques[x]]=-;
else ans[ques[x]]=Ans+ll[ques[x]];
}
} char s[maxn],t[maxn];
int main()
{
scanf("%s",s); n=strlen(s);
lq=qread();
for (int i=;i<=lq;i++)
{
kk[i]=qread();
scanf("%s",t); ll[i]=strlen(t);
ques[ac.insert(t,i)]=i;
} ac.makefail();
ac.buildtree();
ac.pei(s);
bing();
for (int i=;i<=lq;i++) printf("%d\n",ans[i]);
return ;
}

Codeforces963D. Frequency of String的更多相关文章

  1. Codeforces963C Frequency of String 【字符串】【AC自动机】

    题目大意: 给一个串s和很多模式串,对每个模式串求s的一个最短的子串使得这个子串中包含至少k个该模式串. 题目分析: 均摊分析,有sqrt(n)种长度不同的模式串,所以有关的串只有msqrt(n)种. ...

  2. CodeForces - 963D:Frequency of String (bitset暴力搞)

    You are given a string ss. You should answer nn queries. The ii-th query consists of integer kiki an ...

  3. CF963D Frequency of String

    https://codeforces.com/problemset/problem/123/D 题目大意 给一个字符串 \(s\),每次询问一个字符串 \(m_i\) 和一个正整数 \(k_i\),问 ...

  4. Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1)D. Frequency of String

    题意:有一个串s,n个串模式串t,问s的子串中长度最小的包含t k次的长度是多少 题解:把所有t建ac自动机,把s在ac自动机上匹配.保存每个模式串在s中出现的位置.这里由于t两两不同最多只有xsqr ...

  5. Frequency of String CodeForces - 963D

    http://codeforces.com/contest/963/problem/D 题解:https://www.cnblogs.com/Blue233333/p/8881614.html 记M为 ...

  6. 利用JAVA计算TFIDF和Cosine相似度-学习版本

    写在前面的话,既然是学习版本,那么就不是一个好用的工程实现版本,整套代码全部使用List进行匹配效率可想而知. [原文转自]:http://computergodzilla.blogspot.com/ ...

  7. Chp17: Moderate

    17.1 swap a number in place.(without temporary variables) a = a ^ b; b = a ^ b; a = a ^ b; 17.3 Writ ...

  8. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅲ

    3.1.3 用例举例 在学习它的实现之前我们还是应该先看看如何使用它.相应的我们这里考察两个用例:一个用来跟踪算法在小规模输入下的行为测试用例和一个来寻找更高效的实现的性能测试用例. 3.1.3.1 ...

  9. Jason Wang: 结对编程 CountWord(第三次作业)

    本次作业地址: https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882 学号: 201731072323 ...

随机推荐

  1. decompressedResponseImageOfSize:completionHandler:]_block_invoke

    原因:   It turns out the linker error was caused by the CGImageSourceCreateWithData call. And the root ...

  2. SSave ALAsset image to disk fast on iOS

    I am using ALAsset to retrieve images like that: [[asset defaultRepresentation] fullResolutionImage] ...

  3. 团队作业-Beta冲刺第二天

    这个作业属于哪个课程 <https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1> 这个作业要求在哪里 <https ...

  4. iview table里面 插入下拉列表组件(自定义组件)一定要加key,不加key,table开始会加载所有数据,然后再从第2页点回第一页,就会走onChange事件,混乱的逻辑,切记加:key

    iview table里面 插入下拉列表组件(自定义组件)一定要加key,不加key,table开始会加载所有数据,然后再从第2页点回第一页,就会走onChange事件,混乱的逻辑,切记加:key 关 ...

  5. 判断NumLock键和CapsLock键是否被锁定

    实现效果: 知识运用: AIP函数GetKeyState //针对已处理过的按键 在最近一次输入信息时 判断指定虚拟键的状态 intkey:预测试的虚拟键键码 实现代码: [DllImport(&qu ...

  6. java B转换KB MB GB TB PB EB ZB

    public static String readableFileSize(long size) { if (size <= 0) { return "0"; } final ...

  7. ios之UITextView

    我们计划创建UITextView,实现UITextViewDelegate协议方法,使用NSLog检查该方法何时被调用.我们还会接触到如何在TextView中限制字符的数量,以及如何使用return键 ...

  8. Spring入门Ioc、DI笔记

    Spring是为解决企业应用程序开发复杂性而创建的一个Java开源框架.以下是本人学习过程中总结的一些笔记: 如何学习Spring - 掌握用法 - 深入理解 - 反复总结 - 再次深入理解和实践 s ...

  9. js事件(事件冒泡与事件捕获)

    事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题. <div id='aa' click='po'> <p id='bb' cli ...

  10. 【数论 dp】2048

    考场上一个DFS优化乱加就对了一个无解的点 题目描述 给定一个长度为 n 的数列,在这个数列中选取一个子序列使得这个子序列中的数能合出2048 对于合并操作,可以选择这个序列中的任意两个数进行合并,当 ...