zoukankan      html  css  js  c++  java
  • Barty's Computer 字典树

    https://nanti.jisuanke.com/t/17122

    Barty have a computer, it can do these two things.

    1. Add a new string to its memory, the length of this string is even.

    2. For given 44 strings a,b,c,da,b,c,d, find out how many strings that can be product by a+s1+b+c+s2+da+s1+b+c+s2+d, and |a| + |s1| + |b| = |c| + |s2| + |d|a+s1+b=c+s2+d∣. |s|s∣ means the length of string ss, s1s1 and s2s2 can be any string, including "".

    Please help your computer to do these things.

    Input Format

    Test cases begins with T(T le 5)T(T5).

    Then TT test cases follows.

    Each test case begins with an integer Q(Q le 30000)Q(Q30000).

    Then QQ lines,

    1 s: add a new string ss to its memory.

    2 a b c d: find how many strings satisfying the requirement above.

    sum |s| + |a| + |b| + |c| + |d| le 2000000s+a+b+c+d2000000.

    Output Format

    For type 22 query. Output the answer in one line.

    样例输入

    1
    10
    1 abcqaq
    1 abcabcqaqqaq
    2 ab bc qa aq
    2 a c q q
    1 abcabcqaqqwq
    2 ab bc qa aq
    2 a c q q
    1 abcq
    2 a c q q
    2 a b c q

    样例输出

    1
    2
    1
    3
    3
    1

    题目来源

    2017 ACM-ICPC 亚洲区(西安赛区)网络赛

     

    首先对于每一个主串,都把它对半砍,前缀加入字典树0,前缀逆序加入字典树1,后缀加入字典树2,后缀逆序加入字典树3

    所以每一个节点都开一个vector存着有哪些主串能经过这个节点。内存复杂度玄学

    然后每次询问,用a去字典树0找,就能知道有哪些主串能匹配a

    同理b、c、d,然后求一个交集即可。

    这样会有些不合法

    比如就是会使得

    ab  bc这样,结合成abc

    所以要用长度来判断是否合法,

    lenstr(a) + lenstr(b)不能大于lenstr (s) / 2

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int N = 26, maxn = 2e6 + 2;
    struct Node {
        vector<int> vc;
        struct Node * pNext[N];
    } tree[4][500000 + 2];
    int t[4];
    int len[maxn];
    char str[maxn];
    char a[maxn], b[maxn], c[maxn], d[maxn];
    struct Node * create(int id) {
        struct Node * p = &tree[id][t[id]++];
        p->vc.clear();
        for (int i = 0; i < N; ++i) p->pNext[i] = NULL;
        return p;
    }
    void toInset(struct Node **T, char str[], int be, int en, int flag, int id, int which) {
        struct Node *p = *T;
        if (p == NULL) {
            p = *T = create(id);
        }
        if (flag == -1) {
            for (int i = en; i >= be; --i) {
                int tid = str[i] - 'a';
                if (!p->pNext[tid]) p->pNext[tid] = create(id);
                p = p->pNext[tid];
                p->vc.push_back(which);
            }
        } else {
            for (int i = be; i <= en; ++i) {
                int tid = str[i] - 'a';
                if (!p->pNext[tid]) {
                    p->pNext[tid] = create(id);
                }
                p = p->pNext[tid];
                p->vc.push_back(which);
            }
        }
    }
    int vis[4][maxn], DFN;
    bool flag;
    void ask(struct Node *T, char str[], int be, int en, int flag, int which) {
        struct Node *p = T;
        if (p == NULL) {
            flag = true;
            return;
        }
        if (flag == -1) {
            for (int i = en; i >= be; --i) {
                int id = str[i] - 'a';
                if (!p->pNext[id]) {
                    flag = true;
                    return ;
                }
                p = p->pNext[id];
            }
            for (int i = 0; i < p->vc.size(); ++i) {
                vis[which][p->vc[i]] = DFN;
            }
        } else {
            for (int i = be; i <= en; ++i) {
                int id = str[i] - 'a';
                if (!p->pNext[id]) {
                    flag = true;
                    return ;
                }
                p = p->pNext[id];
            }
    //        printf("fff");
    //        printf("%d * * ** 
    ", p->vc.size());
            for (int i = 0; i < p->vc.size(); ++i) {
                vis[which][p->vc[i]] = DFN;
            }
        }
    }
    void work() {
        t[0] = t[1] = t[2] = t[3] = 0;
        struct Node *T[4];
        for (int i = 0; i < 4; ++i) T[i] = NULL;
        int q;
        scanf("%d", &q);
        int now = 0;
        while (q--) {
            int op;
            scanf("%d", &op);
            if (op == 1) {
                scanf("%s", str + 1);
                len[++now] = strlen(str + 1);
                toInset(&T[0], str, 1, len[now] / 2, 1, 0, now);
                toInset(&T[1], str, 1, len[now] / 2, -1, 1, now);
                toInset(&T[2], str, len[now] / 2 + 1, len[now], 1, 2, now);
                toInset(&T[3], str, len[now] / 2 + 1, len[now], -1, 3, now);
            } else {
                scanf("%s%s%s%s", a + 1, b + 1, c + 1, d + 1);
                ++DFN, flag = false;
                int lena = strlen(a + 1), lenb = strlen(b + 1), lenc = strlen(c + 1), lend = strlen(d + 1);
                ask(T[0], a, 1, lena, 1, 0);
                if (flag) {
                    printf("0
    ");
                    continue;
                }
                ask(T[1], b, 1, lenb, -1, 1);
                if (flag) {
                    printf("0
    ");
                    continue;
                }
                ask(T[2], c, 1, lenc, 1, 2);
                if (flag) {
                    printf("0
    ");
                    continue;
                }
                ask(T[3], d, 1, lend, -1, 3);
                if (flag) {
                    printf("0
    ");
                    continue;
                }
                int ans = 0;
    //            for (int i = 1; i <= now; ++i) {
    //                printf("%d %d %d %d
    ", vis[0][i], vis[1][i], vis[2][i], vis[3][i]);
    //            }
    //            printf("*************
    ");
                for (int i = 1; i <= now; ++i) {
                    if (vis[0][i] == DFN && vis[1][i] == DFN && vis[2][i] == DFN && vis[3][i] == DFN && lena + lenb <= len[i] / 2 && lenc + lend <= len[i] / 2)
                        ans++;
                }
                printf("%d
    ", ans);
            }
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    百度网盘下载速度慢的问题解决
    问题汇总
    centos 遇到Name or service not known
    centos7 下 python3 和python2 同时存在但是无法使用pip3 的解决方案
    pycharm2020(最简单的方法)配置远程连接服务器
    pycharm2020.1.2激活
    centos安装成功bart标注工具
    keras遇到bert实战一(bert实现分类)
    使用Array.slice(0) 实现数组浅拷贝
    try/catch/finally 语句
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7534818.html
Copyright © 2011-2022 走看看