zoukankan      html  css  js  c++  java
  • ZOJ 3228 Searching the String (AC自己主动机)

    题目链接:Searching the String


    解析:给一个长串。给n个不同种类的短串。问分别在能重叠下或者不能重叠下短串在长串中出现的次数。

    能重叠的已经是最简单的AC自己主动机模板题了。

    不能重叠的记录一下每一个匹配的串的起始位置保证不重叠就可以。



    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Trie{
        int next[600010][26], fail[600010], deep[600010];
        int root, L;
    
        int newnode(){
            for(int i = 0; i < 26; i++) next[L][i] = -1;
            L ++;
            return L-1;
        }
    
        void init(){
            L = 0;
            root = newnode();
            deep[root] = 0;
        }
    
        int insert(char buf[]){
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++){
                if(next[now][ buf[i] - 'a' ] == -1){
                    next[now][ buf[i] - 'a' ] = newnode();
                    deep[next[now][buf[i] - 'a']] = i+1;
                }
                now = next[now][ buf[i] - 'a' ];
            }
            return now;
        }
    
        void build(){
            queue<int> Q;
            fail[root] = root;
            for(int i = 0; i < 26; i++){
                if(next[root][i] == -1) next[root][i] = root;
                else{
                    fail[ next[root][i] ] = root;
                    Q.push(next[root][i]);
                }
            }
            while(!Q.empty()){
                int now = Q.front();
                Q.pop();
                for(int i = 0; i < 26; i++){
                    if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i];
                    else{
                        fail[ next[now][i] ] = next[ fail[now] ][i];
                        Q.push(next[now][i]);
                    }
                }
            }
        }
    
        int cnt[600010][2];   //cnt[][0]表示能重叠的,cnt[][1]表示不能重叠的
        int last[600010];    //上次匹配的字符
        void query(char buf[]){
            memset(cnt, 0, sizeof(cnt));
            memset(last, -1, sizeof(last));
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++){
                now = next[now][ buf[i] - 'a' ];
                int temp = now;
                while(temp != root){
                    cnt[temp][0] ++;
                    if(i - last[temp] >= deep[temp]){    //保证不重叠
                        last[temp] = i;
                        cnt[temp][1] ++;
                    }
                    temp = fail[temp];
                }
            }
        }
    };
    
    char buf[20];
    char str[100010];
    int typ[100010], pos[100010];
    Trie ac;
    
    int main(){
        #ifdef sxk
            freopen("in.txt", "r", stdin);
        #endif //sxk
    
        int n;
        int kase = 0;
        while(scanf("%s", str) == 1){
            scanf("%d", &n);
            ac.init();
            for(int i = 0; i < n; i++){
                scanf("%d%s", &typ[i], buf);
                pos[i] = ac.insert(buf);
            }
            ac.build();
            ac.query(str);
            printf("Case %d
    ", ++kase);
            for(int i=0; i<n; i++)
                printf("%d
    ", ac.cnt[pos[i]][typ[i]]);
            printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    P4141 消失之物(退背包模板)
    P5829 【模板】失配树
    P4827 [国家集训队] Crash 的文明世界
    P4074 [WC2013]糖果公园
    P3242 [HNOI2015]接水果
    P2371 [国家集训队]墨墨的等式
    P4819 [中山市选]杀人游戏
    P5331 [SNOI2019]通信
    BZOJ1082 [SCOI2005]栅栏
    poj1475 Pushing Boxes[双重BFS(毒瘤搜索题)]
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7190571.html
Copyright © 2011-2022 走看看