• (Next树70pts MLE*3)[NOI2011] 阿狸的打字机


    一个会MLE的next树做法,边插入边递推fail数组(next数组,写的时候没学,自己根据ac自动机改的)

    #include<bits/stdc++.h>
    #define ll long long
    #define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    int tr[maxn][26], cnt = 0;
    int fail[maxn];
    
    int f[maxn], d[maxn];
    
    int now = 0;
    
    void insert(string& s, char c)
    {
        int i = c - 'a';
        if (!tr[now][i])
        {
            tr[now][i] = ++cnt;
            d[cnt] = d[now] + 1;
            f[cnt] = now;
            now = tr[now][i];
            //递推fail
            int st = fail[f[now]], j = d[st] - 1;
            while (st && s[j + 1] - 'a' != i)
                j -= d[st], st = fail[st], j += d[st];
            if (j + 1 < s.length() && s[j + 1] - 'a' == i)
                fail[now] = tr[st][i];
            else
                fail[now] = 0;
        }
        else
            now = tr[now][i];
    }
    
    int main()
    {
        fastio;
        fail[0] = 0;
        d[0] = 0;
        cnt = 0;
        memset(tr, NULL, sizeof(tr));
        string p;
        cin >> p;
        string s = "";
        int id = 0;
        vector<string>mp;
        mp.push_back(" ");
        for (int i = 0; i < p.length(); i++)
        {
            char c = p[i];
            if (c == 'P')
            {
                ++id;
                mp.push_back(s);
            }
            else if (c == 'B')
            {
                now = f[now];
                s.pop_back();
            }
            else
            {
                insert(s,c);
                s += c;
            }
        }
    
        int q;
        cin >> q;
        while (q--)
        {
            int x, y;
            cin >> x >> y;
            string& a = mp[x];
            string& b = mp[y];
            //求a在b中出现多少次
            int ans = 0, j = -1, now = 0;
            for (int i = 0; i < b.length(); i++)
            {
                int to = a[j + 1] - 'a';
                while (~j && a[j + 1] != b[i])
                {
                    j -= d[now], now = fail[now], j += d[now];
                    to = a[j + 1] - 'a';
                }
                if (a[j + 1] == b[i])
                {
                    now = tr[now][to];
                    j++;
                    if (j == a.length() - 1)
                        ans++, j -= d[now], now = fail[now], j += d[now];
                }
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    pdflush的工作原理
    proc/sys/net/ipv4/下各项的意义
    Linux系统调用--getrlimit()与setrlimit()函数详解
    定位多线程内存越界问题实践总结
    Linux动态频率调节系统CPUFreq之三:governor
    Linux动态频率调节系统CPUFreq之二:核心(core)架构与API
    Linux动态频率调节系统CPUFreq之一:概述
    ubuntu cpu频率控制
    ThinkPHP5.1的数据库链接和增删改查
    php 常用的常量
  • 原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/15189495.html
Copyright © 2020-2023  润新知