$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. mac ssd开启trim模式

    开启方法 sudo trimforce enable

  2. Fedora19 有关输入法的无法切换问题 和 终端的快捷设置问题

    Fedora19 有关输入法的无法切换问题 和 终端的快捷设置问题 1.首先,要单击右上角的设置输入法的"区域与语言设置",要设置为“为每个窗口设置不同的输入源”. 还有,刚使用的 ...

  3. 一个batch如何通过一个网络

    一个batch下所有的图片一起经过整个网络,不是说一张图片经过网络后再让下一张进入网络,这样一个batch一起通过网络计算速度比一张一张这样快

  4. 把apk文件拖到re-sign.jar运行打开的界面找不到指定文件

    下载一个zipalign.exe放到tools目录下面就可以了 点击下载

  5. js 字符串加密

    加密: 1.获得要加密的字符串:var str=input.value; 2.转化: for(var i=0;i<str.length;i++){ str+=String.fromCharCod ...

  6. 关于$test$plusargs和$value$plusargs的小结

    见: http://www.cnblogs.com/nanoty/p/4355245.html

  7. 【java】抽象类继承关系

    抽象类: 抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充. 一个类不能同时被 abstract 和 final 修饰.如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将 ...

  8. **没有规则可以创建“XXX”需要的目标“XXX”问题的解决方案

    一.现象 我将之前Redhat9.0编译好的uboot,转到ubuntu12.04环境.在ubuntu环境下对 uboot重新编译提示错误.编译过程如下: root@hailin-virtual-ma ...

  9. Python模块之OS,subprocess

    1.os 模块 简述: os 表示操作系统 该模块主要用来处理与系统相关操作 最常用的是文件操作 打开 获取 写入 删除 复制 重命名 常用操作 os.getcwd() : 返回当前文件所在文件夹路径 ...

  10. Python数据类型(简单入门)

    数据类型(预了解) 1.数字类型 整型:int 即不带小数点的数,通常用来标识年龄,账号,身份证号,等级等整数. 浮点型:float 即带有小数点的数,通常用来标记身高,体重,科学计算等有小数点的数. ...