zoukankan      html  css  js  c++  java
  • Searching the String

    题目大意:首先给你一下母串,长度不超过10^5,然后有 N(10^5) 次查询,每次查询有两种命令,0或者1,然后加一个子串,询问母串里面有多少个子串,0表示可以重复,1表示不可以重复。
     
    分析:发现查询的次数是比较多的,然后可以利用查询的串建立一个trie,然后用母串跑一遍就行了,不过有两种操作比较麻烦一些,不过我们可以保存查询时每个节点的查询结果,然后每个串都对应一个节点,最后输出查询结果即可,这样也可以规避掉重复串的问题。
     
    代码如下:
    ===============================================================================================================
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 6e5+7;
    const int MaxSon = 26;
    
    char MumStr[MAXN];
    int Num[MAXN], op[MAXN];
    
    struct Ac_Trie
    {
        int next[MAXN][MaxSon];
        int Fail[MAXN];
        ///End保存每个单词匹配成功后最后面的位置
        ///如果这个节点是一个单词,Len保存这个单词的长度
        int End[MAXN], Len[MAXN];
        int ans[MAXN][2];///保存两种状态的答案
        int root, cnt;
    
        int newnode()
        {
            for(int i=0; i<MaxSon; i++)
                next[cnt][i] = -1;
            Len[cnt] = Fail[cnt] = false;
            End[cnt] = -10;
            ans[cnt][0] = ans[cnt][1] = 0;
    
            return cnt++;
        }
        void InIt()
        {
            cnt = 0;
            root = newnode();
        }
        int Insert(char s[])
        {///返回这个字符串对应的节点编号
            int i, now = root;
    
            for(i=0; s[i]; i++)
            {
                int k = s[i] - 'a';
    
                if(next[now][k] == -1)
                    next[now][k] = newnode();
                now = next[now][k];
            }
    
            Len[now] = i;
    
            return now;
        }
        void GetFail()
        {
            queue<int> Q;
            int i, now = root;
    
            for(i=0; i<MaxSon; i++)
            {
                if(next[now][i] == -1)
                    next[now][i] = root;
                else
                {
                    Fail[next[now][i]] = root;
                    Q.push(next[now][i]);
                }
            }
    
            while(Q.size())
            {
                now = Q.front();
                Q.pop();
    
                for(i=0; i<MaxSon; 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]);
                    }
                }
            }
        }
        void Query(char MumStr[])
        {
            int i, now = root, temp;
    
            for(i=0; MumStr[i]; i++)
            {
                int k = MumStr[i] - 'a';
    
                now = next[now][k];
    
                if(!now)continue;
    
                temp = now;
    
                while(temp != root)
                {
                    if(Len[temp])
                        ans[temp][0]++;
                    if(Len[temp] && (i-End[temp] >= Len[temp]) )
                        ans[temp][1]++, End[temp] = i;
    
                    temp = Fail[temp];
                }
            }
        }
    };
    Ac_Trie ac;
    int main()
    {
        int i, M, t=1;
    
        while(scanf("%s", MumStr) != EOF)
        {
            char s[10];
            ac.InIt();
    
            scanf("%d", &M);
    
            for(i=1; i<=M; i++)
            {
                scanf("%d%s", &op[i], s);
                Num[i] = ac.Insert(s);
            }
    
            ac.GetFail();
            ac.Query(MumStr);
    
            printf("Case %d
    ", t++);
            for(i=1; i<=M; i++)
                printf("%d
    ", ac.ans[Num[i]][op[i]]);
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    HDU 1004 Let the Balloon Rise【STL<map>】
    UVA 1030
    UVA 10881
    POJ 3154 Graveyard【多解,数论,贪心】
    浅谈Notepad++选中行操作+快捷键+使用技巧【超详解】
    COGS 68. [NOIP2005] 采药【01背包复习】
    [phomeflashpic]怎样调用帝国CMS图片幻灯效果
    微信认证新增公对公账户银行卡转账支付审核费用 缩减认证审核时长
    微信公众平台回复过了怎么不能再次回复?亲们要注意查看"公众平台回复用户消息时限变更通知"的公告啊
    新版微信终于支持消息撤回了 微信零钱也能转账了[微信5.3.1.16更新]
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4760679.html
Copyright © 2011-2022 走看看