题目大意:

  给一个串s和很多模式串,对每个模式串求s的一个最短的子串使得这个子串中包含至少k个该模式串。

题目分析:

  均摊分析,有sqrt(n)种长度不同的模式串,所以有关的串只有msqrt(n)种。暴力用AC自动机找出来即可。

代码:

  

 #include<bits/stdc++.h>
using namespace std; const int maxn = ;
const int sigma = ; int n,num,root,d[maxn],fa[maxn],fail[maxn],Ex[maxn];
string str,query[maxn];
vector<int> ans[maxn]; int Number(char ch){return (int)(ch-'a');} struct trie{int data,end,nxt[sigma];}T[maxn]; void insert(int now,int pla,int tnode){
if(pla == query[now].size()){T[tnode].end=now;return;}
int p = Number(query[now][pla]);
if(T[tnode].nxt[p]){insert(now,pla+,T[tnode].nxt[p]);}
else{
num++;T[tnode].nxt[p] = num;T[num].data = p;
fa[num] = tnode; insert(now,pla+,num);
}
} void read(){
cin >> str >> n;
for(int i=;i<=n;i++){
cin >> d[i] >> query[i];
insert(i,,root);
}
} queue <int> q;
void BuildAC(){
for(int i=;i<sigma;i++) if(T[root].nxt[i]) q.push(T[root].nxt[i]);
while(!q.empty()){
int k = q.front();q.pop();
int hh = fail[fa[k]];
while(hh != root){
if(T[hh].nxt[T[k].data]){fail[k]=T[hh].nxt[T[k].data];break;}
else hh = fail[hh];
}
if(T[hh].nxt[T[k].data]&&(!fail[k])&&T[hh].nxt[T[k].data]!=k){
fail[k]=T[hh].nxt[T[k].data];
}
for(int i=;i<sigma;i++) if(T[k].nxt[i]) q.push(T[k].nxt[i]);
}
} void BuildExtraFail(){
q.push(root);
while(!q.empty()){
int k = q.front();q.pop();
int hh = fail[k];
if(T[hh].end){Ex[k] = hh;}else Ex[k] = Ex[hh];
for(int i=;i<sigma;i++) if(T[k].nxt[i]) q.push(T[k].nxt[i]);
}
} void RunAC(){
int now = root;
for(int i=;i<str.length();i++){
int p = Number(str[i]);
if(T[now].nxt[p]) now = T[now].nxt[p];
else{
int hh = fail[now];
int fg = false;
while(hh != root){
if(T[hh].nxt[p]){fg=;now=T[hh].nxt[p];break;}
else hh = fail[hh];
}
if(fg == )goto loop;
if(T[hh].nxt[T[p].data])now=T[hh].nxt[T[p].data];
else now = root;
}
loop:int z = Ex[now];
if(T[now].end) ans[T[now].end].push_back(i);
while(z!=root){ans[T[z].end].push_back(i);z=Ex[z];}
}
} int Min(int a,int b){return a<b?a:b;} void work(){
BuildAC();
BuildExtraFail();
RunAC();
for(int i=;i<=n;i++){
if(ans[i].size()<d[i]){cout<<-<<endl;continue;}
int minn = ;
for(int j=d[i]-;j<ans[i].size();j++){
minn = Min(minn,ans[i][j]-ans[i][j-d[i]+]+query[i].length());
}
cout<<minn<<endl;
}
} int main(){
read();
work();
return ;
}

最新文章

  1. c#中对txt文件的读取与写入,针对二维数组
  2. [转]C++模板学习
  3. 14个Xcode中常用的快捷键操作(转)
  4. linux /usr/bin/ld cannot find 解决
  5. javascript计算字符串的字节长度
  6. ASP.NET自定义错误页面
  7. poj 1995 Raising Modulo Numbers【快速幂】
  8. 【技术宅11】php入门运算
  9. WinFrom玩转config配置文件
  10. Light oj 1030 概率DP
  11. Kindeditor JS 富文本编辑器图片上传指定路径
  12. Python学习--列表和元组
  13. Python_linux环境变量和软链接(个人理解)
  14. 补习系列(7)-springboot 实现拦截的五种姿势
  15. 《转》studio界面、快捷键
  16. #ifndef HeaderName_h #define HeaderName_h #endif 使用详解(转)
  17. 谈谈那些年我们装B的并发编程
  18. 如何把SVG小图片转换为 html字体图表
  19. 构造并发送Beacon帧以伪造任意WiFi热点
  20. [翻译] ios-image-filters

热门文章

  1. 朱晔和你聊Spring系列S1E7:简单好用的Spring Boot Actuator
  2. OO博客作业3:第9-11周作业总结
  3. SQL Server 跨服务器查询
  4. 这款APP太像微信 腾讯起诉索赔1000万
  5. Day1 Numerical simulation of optical wave propagation之标量衍射理论基本原理(一)
  6. PyCharm中快速给选中的代码加上{}、&lt;&gt;、()、[]
  7. 【Python3练习题 020】 求1+2!+3!+...+20!的和
  8. Window.scrollTo()
  9. 项目中常用的MySQL 优化
  10. mysql异常:Packet for query is too large (10240 &gt; 1024). You can change this value