zoukankan      html  css  js  c++  java
  • zoj 3228 覆盖及非覆盖串的多次匹配

     题目题意:

    给定多个小串,在一个长串中寻找这些串的匹配次数,有些统计的是可覆盖的,有些统计的是非覆盖的

    先可以简单理解一下,建立ac自动机后,当前节点包含的字符串必然被把它作为fail指针的节点包含,所以一开始写了个set[MAX],然后MLE了

    如果一个当前串被完全访问了,那么这个串一定是在整个fail指针的最后面的,所以那个节点在访问中一直沿着fail指针往下走一定是能走到的,在记录一个

    上一次访问的位置,就能判断当前位置是否重复覆盖了

    然后根据初始记录的字符串对应的节点位置,输出在那个节点的访问次数就行了

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <queue>
      5 #include <set>
      6 using namespace std;
      7 #define clr(x) memset(x , 0 , sizeof(x))
      8 #define CHAR_SIZE 26
      9 #define MAX_SIZE 600010
     10 #define N 100005
     11 char str[MAX_SIZE];
     12 char s[1005];
     13 int n ,  cnt[MAX_SIZE][2];
     14 int pos[N] , flag[N];
     15 struct AC_Machine{
     16     int sz , ch[MAX_SIZE][CHAR_SIZE] , fail[MAX_SIZE] , deep[MAX_SIZE] , val[MAX_SIZE] , pre[MAX_SIZE];
     17     void init(){
     18         sz = 1;
     19         clr(ch[0]) , clr(val);
     20         pre[0] = 0;
     21         cnt[0][0] = cnt[1][0] = 0;
     22     }
     23 
     24     void insert(char *s , int p){
     25         int n = strlen(s) , u=0;
     26         for(int i=0 ; i<n ; i++){
     27             int c = s[i]-'a';
     28             if(!ch[u][c]){
     29                 clr(ch[sz]);
     30                 cnt[sz][0] = cnt[sz][1] = pre[sz] = val[sz] = 0;
     31                 ch[u][c] = sz++;
     32             }
     33             u = ch[u][c];
     34             deep[u] = i+1;
     35         }
     36         val[u] = 1;
     37         pos[p] = u;
     38     }
     39 
     40     void get_fail(){
     41         queue<int> Q;
     42         fail[0] = 0;
     43         for(int c=0 ; c<CHAR_SIZE ; c++){
     44             int u = ch[0][c];
     45             if(u) {Q.push(u);fail[u]=0;}
     46         }
     47         while(!Q.empty()){
     48             int r = Q.front();
     49             val[r] |= val[fail[r]];
     50             Q.pop();
     51             for(int c=0 ; c<CHAR_SIZE ; c++){
     52                 int u = ch[r][c];
     53                 if(!u){ch[r][c]=ch[fail[r]][c] ; continue;}
     54                 fail[u] = ch[fail[r]][c];
     55                 Q.push(u);
     56             }
     57         }
     58     }
     59 }ac;
     60 
     61 void solve()
     62 {
     63     int cur = 0 , n=strlen(str);
     64     for(int i=1 ; i<=n ; i++){
     65         int c = str[i-1]-'a';
     66         cur = ac.ch[cur][c];
     67         int v = cur;
     68         while(v && ac.val[v]){
     69             cnt[v][0]++;
     70           //  cout<<str[i-1]<<" "<<v<<endl;
     71             if(i-ac.pre[v]>=ac.deep[v]){
     72                 cnt[v][1]++;
     73                 ac.pre[v] = i;
     74             }
     75             v = ac.fail[v];
     76         }
     77     }
     78 }
     79 
     80 int main()
     81 {
     82   //  freopen("in.txt" , "r" , stdin);
     83     int cas = 0;
     84     while(~scanf("%s" , str))
     85     {
     86         printf("Case %d
    " , ++cas);
     87         scanf("%d" , &n);
     88         int op;
     89         ac.init();
     90         for(int i=1 ; i<=n ; i++){
     91             scanf("%d%s" , &op , s);
     92             flag[i] = op;
     93             ac.insert(s , i);
     94         }
     95         ac.get_fail();
     96         solve();
     97 
     98         for(int i=1 ; i<=n ; i++){
     99             printf("%d
    " , cnt[pos[i]][flag[i]]);
    100         }
    101         puts("");
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    ALOS卫星概况
    如何安装和配置jdk6u18windowsi586.exe
    请问是否可以直接发布切片好的服务 arcgis serever
    eclipse and myeclipse
    GISer还有机会屌丝逆袭吗?
    ArcGIS中加载百度地图
    细说委托
    白话地图投影之Proj.4地图投影库简介
    让OpenLayers添加百度地图(未完版)
    白话地图投影之墨卡托投影
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4744146.html
Copyright © 2011-2022 走看看