zoukankan      html  css  js  c++  java
  • hdu 5384 AC自动机

    AC自动机裸题,真的很裸……

    先把前面的 n 个待匹配串存起来,再把后面 m 个模式串构造 AC自动机,然后再一个个询问待匹配串就没了……

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 using namespace std;
     5 const int maxm=600006;
     6 
     7 char s[100005][10005],word[10005];
     8 int nxt[maxm][26],tail[maxm],f[maxm],size;
     9 int last[maxm];
    10 
    11 int newnode(){
    12     memset(nxt[size],0,sizeof(nxt[size]));
    13     f[size]=tail[size]=0;
    14     return size++;
    15 }
    16 
    17 void insert(char s[]){
    18     int i,p=0;
    19     for(i=0;s[i];i++){
    20         int &x=nxt[p][s[i]-'a'];
    21         p=x?x:x=newnode();
    22     }
    23     tail[p]++;
    24 }
    25 
    26 void makenxt(){
    27     int i;
    28     queue<int>q;
    29     f[0]=0;
    30     for(i=0;i<26;i++){
    31         int v=nxt[0][i];
    32         if(v){
    33             f[v]=last[v]=0;
    34             q.push(v);
    35         }
    36     }
    37     while(!q.empty()){
    38         int u=q.front();
    39         q.pop();
    40         for(i=0;i<26;i++){
    41             int v=nxt[u][i];
    42             if(!v)nxt[u][i]=nxt[f[u]][i];
    43             else{
    44                 q.push(v);
    45                 f[v]=nxt[f[u]][i];
    46                 last[v]=tail[f[v]]?f[v]:last[f[v]];
    47             }
    48         }
    49     }
    50 }
    51 
    52 int query(char s[]){
    53     int ans=0,v=0;
    54     for(int i=0;s[i];i++){
    55         while(v&&!nxt[v][s[i]-'a'])v=f[v];
    56         v=nxt[v][s[i]-'a'];
    57         int tmp=v;
    58         while(tmp){
    59             ans+=tail[tmp];
    60             tmp=last[tmp];
    61         }
    62     }
    63     return ans;
    64 }
    65 
    66 int main(){
    67     int T;
    68     scanf("%d",&T);
    69     while(T--){
    70         int n,m;
    71         scanf("%d%d",&n,&m);
    72         size=0,newnode();
    73         for(int i=0;i<n;++i){
    74             scanf("%s",s[i]);
    75         }
    76         for(int i=0;i<m;++i){
    77             scanf("%s",word);
    78             insert(word);
    79         }
    80         makenxt();
    81         for(int i=0;i<n;++i){
    82             printf("%d
    ",query(s[i]));
    83         }
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    redis内存模型、内存使用的优化
    【转】[Andriod]Xposed和VirtualXposed
    https详解
    http详解
    补码
    浮点数的二进制表示
    Go随机数
    ECDSA--圆锥曲线数字签名算法原理(摘wikepedia)
    Linux命令备忘
    【Windows】系统命令
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4728408.html
Copyright © 2011-2022 走看看