$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. 上下文 xx

    上下文,就是指在程序中的某个位置,可以访问到的所有资源的总和. 具体说来,在程序中资源可能是一个变量.一个常量.一个类的引用等等.

  2. 使用prelu

    一个使用方式:http://blog.csdn.net/xg123321123/article/details/52610919 还有一种是像relu那样写,我就是采用的这种方式,直接把名字从relu ...

  3. 快学UiAutomator UiDevice API 详解

    一.按键使用 返回值 方法名 说明 boolean pressBack() 模拟短按返回back键 boolean pressDPadCenter() 模拟按轨迹球中点按键 boolean press ...

  4. mysql的字符串处理函数用法

    1.LOCATE函数 LOCATE(substr,str) 返回子串 substr 在字符串 str 中第一次出现的位置.如果子串 substr 在 str 中不存在,返回值为 0.如果substr或 ...

  5. redis:高可用分析

    https://www.cnblogs.com/xuning/p/8464625.html 基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经常在业务中用其 ...

  6. jQuery实现Ajax

    jQuery.ajax([settings]) type:类型,“POST”或“GET”,默认为GET url:发送地址 data:连同请求发送到服务器的数据 dataType:预期服务器返回的数据类 ...

  7. 【php】Windows PHP及xdebug安装 安装

    php version 7.0 redis 下载地址 https://pecl.php.net/package/redis 7.0版本的redis不再依赖php_igbinary.dll扩展,可以独立 ...

  8. Django中模板查找路径配置

  9. 我的Python分析成长之路3

    一 集合                                                                                                 ...

  10. 编写个makefile文件测试patsubst 的作用

    1 SRCS := $(wildcard *.c) 2 OBJS := $(patsubst %.c,%.o,$(SRCS) ) //把$(SRCS)中的文件.c全部换成.o文件 3 all: 4 @ ...