zoukankan      html  css  js  c++  java
  • Codeforces963C Frequency of String 【字符串】【AC自动机】

    题目大意:

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

    题目分析:

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

    代码:

      

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 102000;
      5 const int sigma = 26;
      6 
      7 int n,num,root,d[maxn],fa[maxn],fail[maxn],Ex[maxn];
      8 string str,query[maxn];
      9 vector<int> ans[maxn];
     10 
     11 int Number(char ch){return (int)(ch-'a');}
     12 
     13 struct trie{int data,end,nxt[sigma];}T[maxn];
     14 
     15 void insert(int now,int pla,int tnode){
     16     if(pla == query[now].size()){T[tnode].end=now;return;}
     17     int p = Number(query[now][pla]);
     18     if(T[tnode].nxt[p]){insert(now,pla+1,T[tnode].nxt[p]);}
     19     else{
     20     num++;T[tnode].nxt[p] = num;T[num].data = p;
     21     fa[num] = tnode; insert(now,pla+1,num);
     22     }
     23 }
     24 
     25 void read(){
     26     cin >> str >> n;
     27     for(int i=1;i<=n;i++){
     28     cin >> d[i] >> query[i];
     29     insert(i,0,root);
     30     }
     31 }
     32 
     33 queue <int> q;
     34 void BuildAC(){
     35     for(int i=0;i<sigma;i++) if(T[root].nxt[i]) q.push(T[root].nxt[i]);
     36     while(!q.empty()){
     37     int k = q.front();q.pop();
     38     int hh = fail[fa[k]];
     39     while(hh != root){
     40         if(T[hh].nxt[T[k].data]){fail[k]=T[hh].nxt[T[k].data];break;}
     41         else hh = fail[hh];
     42     }
     43     if(T[hh].nxt[T[k].data]&&(!fail[k])&&T[hh].nxt[T[k].data]!=k){
     44         fail[k]=T[hh].nxt[T[k].data];
     45     }
     46     for(int i=0;i<sigma;i++) if(T[k].nxt[i]) q.push(T[k].nxt[i]);
     47     }
     48 }
     49 
     50 void BuildExtraFail(){
     51     q.push(root);
     52     while(!q.empty()){
     53     int k = q.front();q.pop();
     54     int hh = fail[k];
     55     if(T[hh].end){Ex[k] = hh;}else Ex[k] = Ex[hh];
     56     for(int i=0;i<sigma;i++) if(T[k].nxt[i]) q.push(T[k].nxt[i]);
     57     }
     58 }
     59 
     60 void RunAC(){
     61     int now = root;
     62     for(int i=0;i<str.length();i++){
     63     int p = Number(str[i]);
     64     if(T[now].nxt[p]) now = T[now].nxt[p];
     65     else{
     66         int hh = fail[now];
     67         int fg = false;
     68         while(hh != root){
     69         if(T[hh].nxt[p]){fg=1;now=T[hh].nxt[p];break;}
     70         else hh = fail[hh];
     71         }
     72         if(fg == 1)goto loop;
     73         if(T[hh].nxt[T[p].data])now=T[hh].nxt[T[p].data];
     74         else now = root;
     75     }
     76     loop:int z = Ex[now];
     77     if(T[now].end) ans[T[now].end].push_back(i);
     78     while(z!=root){ans[T[z].end].push_back(i);z=Ex[z];}
     79     }
     80 }
     81 
     82 int Min(int a,int b){return a<b?a:b;}
     83 
     84 void work(){
     85     BuildAC();
     86     BuildExtraFail();
     87     RunAC();
     88     for(int i=1;i<=n;i++){
     89     if(ans[i].size()<d[i]){cout<<-1<<endl;continue;}
     90     int minn = 123456789;
     91     for(int j=d[i]-1;j<ans[i].size();j++){
     92         minn = Min(minn,ans[i][j]-ans[i][j-d[i]+1]+query[i].length());
     93     }
     94     cout<<minn<<endl;
     95     }
     96 }
     97 
     98 int main(){
     99     read();
    100     work();
    101     return 0;
    102 }
  • 相关阅读:
    python之xlwt模块列宽width、行高Heights详解
    Testlink在CentOS、windows安装
    Appium中长按按钮操作
    CentOS oracle Client客户端安装
    WebDriver中自动识别验证码--Python实现
    shell批量重命令文件脚本
    MFC 显示图片
    MFC CEdit控件 自动换行
    第一次社会
    undefined reference 问题各种情况分析
  • 原文地址:https://www.cnblogs.com/Menhera/p/8933790.html
Copyright © 2011-2022 走看看