zoukankan      html  css  js  c++  java
  • [TJOI 2013]单词

    Description

    题库链接

    给出一篇文章的所有单词,询问每个单词出现的次数。

    单词总长 (leq 10^6)

    Solution

    算是 (AC) 自动机的板子,注意拼成文章的时候要在单词间加上个不会出现的字符。同时注意匹配时会访问这个字符,所以在 (trie) 树上要多开一维。

    我的代码慢的飞起...看提交基本都几百 (ms) ,我在超时边缘...

    Code

    //It is made by Awson on 2018.2.5
    #include <bits/stdc++.h>
    #define LL long long 
    #define dob complex<double>
    #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    #define writeln(x) (write(x), putchar('
    '))
    #define lowbit(x) ((x)&(-(x)))
    using namespace std;
    const int N = 1e6+200;
    void read(int &x) {
        char ch; bool flag = 0;
        for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
        for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
        x *= 1-2*flag;
    }
    void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
    void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
    
    queue<int>Q;
    int n, cnt[205], loc = -1, mp[205];
    char T[N+5], S[N+5];
    struct AC_Automaton {
        int ch[N+5][27], val[N+5], f[N+5], pos;
        void insert(int id) {
            int len = strlen(T), u = 0;
            for (int i = 0; i < len; i++) {
                if (ch[u][T[i]-'a'] == 0) ch[u][T[i]-'a'] = ++pos;
                u = ch[u][T[i]-'a'];
            }
            if (val[u] == 0) mp[id] = val[u] = id;
            else mp[id] = val[u];
        }
        void build() {
            while (!Q.empty()) Q.pop();
            for (int i = 0; i < 27; i++) if (ch[0][i]) f[ch[0][i]] = 0, Q.push(ch[0][i]);
            while (!Q.empty()) {
                int u = Q.front(); Q.pop();
                for (int i = 0; i < 27; i++)
                    if (ch[u][i]) f[ch[u][i]] = ch[f[u]][i], Q.push(ch[u][i]);
                    else ch[u][i] = ch[f[u]][i];
            }
        }
        void query() {
            int len = strlen(S), u = 0;
            for (int i = 0; i < len; i++) {
                u = ch[u][S[i]-'a'];
                for (int j = u; j; j = f[j]) if (val[j]) ++cnt[val[j]];
            }
        }
    }AC;
    
    void add() {
        int len = strlen(T); S[++loc] = 'a'+26;
        for (int i = 0; i < len; i++) S[++loc] =  T[i];
    }
    void work() {
        read(n);
        for (int i = 1; i <= n; i++) {
            scanf("%s", T); AC.insert(i); add();
        }
        AC.build(); AC.query();
        for (int i = 1; i <= n; i++) writeln(cnt[mp[i]]);
    }
    int main() {
        work(); return 0;
    }
  • 相关阅读:
    C# checklistbox控件用法总结(怎样得到多选的值,以及动态加载数据)
    Tomcat service.xml详解
    修改windows服务器上面tomcat启动窗口的名称
    表空间
    安装selenium遇到的问题
    oracel 锁表查询
    Can not perform this action after onSaveInstanceState
    Caused by: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.HEADSET_PLUG
    Java.lang.IllegalStateException Activity has been destroyed
    StrictMode 使用
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8417194.html
Copyright © 2011-2022 走看看