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 }
  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/Menhera/p/8933790.html
Copyright © 2011-2022 走看看