• hdu 5384 Danganronpa(字典树)


    题意:

    f(A,B)表示:B在A中作为子串出现的次数。
    题目给出n个证据,m个子弹
    Ai是证据。Bi是子弹。题目问:全部Bi对每一个Ai造成的伤害是多少,即每一个BiAi中出现的次数总和。

    解析:

    不会AC自己主动机,所以就用字典树水了一发。没想到过了。


    先把全部的Bi插入字典树中。然后枚举每一个Ai的后缀,查询后缀的每一个前缀在字典树中出现了几次。

    my code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    using namespace std;
    typedef long long ll;
    const int MAXN = (int)1e5 + 10;
    const int maxnode = (int)6e5 + 10;
    const int sigma_size = 26;
    
    struct Trie {
        int ch[maxnode][sigma_size];
        int val[maxnode];
        int sz;
        void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0]));}
        Trie() {clear();}
        int idx(char c) { return c - 'a';}
    
        void insert(char *s, int v = 1) {
            int u = 0, n = strlen(s);
            for(int i = 0; i < n; i++) {
                int c = idx(s[i]);
                if(!ch[u][c]) {
                    memset(ch[sz], 0, sizeof(ch[u]));
                    val[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] += v;
        }
    
        ll find(const char* s) {
            int u = 0, n = strlen(s);
            ll ret = 0;
            for(int i = 0; i < n; i++) {
                int c = idx(s[i]);
                if(!ch[u][c]) return ret;
                u = ch[u][c];
                ret += val[u];
            }
            return ret;
        }
    } trie;
    
    int n, m;
    string A[MAXN];
    char B[MAXN];
    
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &m);
            trie.clear();
            for(int i = 0; i < n; i++) {
                cin >> A[i];
            }
            for(int i = 0; i < m; i++) {
                scanf("%s", B);
                trie.insert(B);
            }
            ll ans = 0;
            for(int i = 0; i < n; i++) {
                ans = 0;
                for(int j = 0; j < A[i].size(); j++) {
                    ans += trie.find(A[i].c_str()+j);
                }
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    [CTSC2018]暴力写挂
    【bzoj 2870】 最长道路tree
    [CTSC2010]珠宝商
    [JXOI2018]守卫
    [JXOI2018]排序问题
    [AHOI2014/JSOI2014]骑士游戏
    [SNOI2017]遗失的答案
    【LGP5437】【XR-2】约定
    【LGP5349】幂
    hdu-2688 Rotate---树状数组+模拟
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7294482.html
Copyright © 2020-2023  润新知