Codeforces963D. Frequency of String
$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的更多相关文章
- Codeforces963C Frequency of String 【字符串】【AC自动机】
题目大意: 给一个串s和很多模式串,对每个模式串求s的一个最短的子串使得这个子串中包含至少k个该模式串. 题目分析: 均摊分析,有sqrt(n)种长度不同的模式串,所以有关的串只有msqrt(n)种. ...
- 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 ...
- CF963D Frequency of String
https://codeforces.com/problemset/problem/123/D 题目大意 给一个字符串 \(s\),每次询问一个字符串 \(m_i\) 和一个正整数 \(k_i\),问 ...
- 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 ...
- Frequency of String CodeForces - 963D
http://codeforces.com/contest/963/problem/D 题解:https://www.cnblogs.com/Blue233333/p/8881614.html 记M为 ...
- 利用JAVA计算TFIDF和Cosine相似度-学习版本
写在前面的话,既然是学习版本,那么就不是一个好用的工程实现版本,整套代码全部使用List进行匹配效率可想而知. [原文转自]:http://computergodzilla.blogspot.com/ ...
- Chp17: Moderate
17.1 swap a number in place.(without temporary variables) a = a ^ b; b = a ^ b; a = a ^ b; 17.3 Writ ...
- 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅲ
3.1.3 用例举例 在学习它的实现之前我们还是应该先看看如何使用它.相应的我们这里考察两个用例:一个用来跟踪算法在小规模输入下的行为测试用例和一个来寻找更高效的实现的性能测试用例. 3.1.3.1 ...
- Jason Wang: 结对编程 CountWord(第三次作业)
本次作业地址: https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882 学号: 201731072323 ...
随机推荐
- Caused by: java.lang.ClassNotFoundException: java.com.bj186.ssm.controller.UserController
在搭建SpringMVC的时候,遇到的这个问题真的很奇葩, 找不到UserController这个类 这明明不就在工程目录下吗? 经过了一番艰苦卓绝的斗争, 才发现原来是包导少了 之前导入的包是: & ...
- js 两个数组对象根据账号比较去重,解决直接splice后数组索引改变
目的获取Arr2中不包含在arr1中的对象 根据Account进行比较,如果相等则删除tempArr数组对象. 结果返回张三 var arr1=[{"account":" ...
- 人脸识别中的检测(在Opencv中加入了QT)
#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include & ...
- java在线聊天项目0.7版 连接多个客户端问题,开启多个客户端后服务器端只接收到一个 对各种异常的补充处理
问题的原因是 while(connected) { String str=dis.readUTF(); System.out.println(str); } 不断循环执行,一直在死循环获取socket ...
- nginx 无法加载css/js图片等文件 404 not fund
刚配置Nginx反向代理,Nginx可能会出现无法加载css.js或者图片等文件,这里需要在配置文件*.conf里面加上如下配置项. location ~ .*\.(js|css|png|jpg)$ ...
- Centos7下安装iptables防火墙
说明:centos7默认使用的firewalld防火墙,由于习惯使用iptables做防火墙,所以在安装好centos7系统后,会将默认的firewall关闭,并另安装iptables进行防火墙规则设 ...
- python 有4个数字1234,能组成多少个互不相同且无重复的三位数数字。
def output(): count = 0 for i in range(1,5): for j in range(1, 5): for k in range(1, 5): if i==j or ...
- Scrapy爬取多层级网页内容的方式
# -*- coding: utf-8 -*- import scrapy from Avv.items import AvvItem class AvSpider(scrapy.Spider): n ...
- raywenderlich.com Objective-C编码规范
原文链接 : The official raywenderlich.com Objective-C style guide 原文作者 : raywenderlich.com Team 译文出自 : r ...
- 折半查找,binarySearch
折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务.它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比 ...