zoukankan      html  css  js  c++  java
  • bzoj4896 [Thu Summer Camp2016]补退选

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4896

    【题解】

    隔壁thusc画风怎么这么正常啊。。

    三个操作:插入字符串,删除字符串,询问以某字符串为前缀,最早什么时候超过了d个。

    用trie插入然后拿个vector维护第一次超过x个的时间。

    vector中总的元素为60*10w=600w个。所以可以承受。

    然后我们发现非常坑。。

    我们只能用指针写省空间。。然后开了600w的trienode还是MLE了。。

    改成400w就过了(?)看来没去卡。。

    # include <map>
    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 4e6 + 10, N = 310;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    char str[N];
    
    struct trienode {
        trienode *ch[26];
        int w;
        vector<int> v;
    }T[M];
    int cnt = 1;
    
    int nQ;
    inline void add(char *str, int d) {
        trienode *p = &T[1], *q;
        for (int i=0, c; str[i]; ++i) {
            c = str[i] - 'a';
            if(p->ch[c] == 0) {
                ++cnt;
                q = &T[cnt];
                p->ch[c] = q;
            }
            p = p->ch[c];
            p->w += d;
            if((p->v).size() < p->w) p->v.push_back(nQ);
        }
    }
    
    inline int query(int d) {
    //    printf("d = %d
    ", d);
        trienode *p = &T[1], *q;
        for (int i=0, c; str[i]; ++i) {
            c = str[i] - 'a';
            if(p->ch[c] == 0) return -1;
            p = p->ch[c];
    //        printf("%d
    ", p->v.size());
        }
        if(p->v.size() > d) return p->v[d];
        else return -1;
    }
    
    
    int main() {
        int q, opt, a, b, c;
        cin >> q;
        int ans = 0;
        for (nQ = 1; nQ <= q; ++nQ) {
            scanf("%d", &opt); 
            scanf("%s", str);
            if(opt == 1) add(str, 1);
            else if(opt == 2) add(str, -1);
            else {
                scanf("%d%d%d", &a, &b, &c);
                ans = query(((ll)a*abs(ans)+b)%c);
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    View Code

    后来看了看popoqqq的博客发现有很多ch[..]是没有用的。

    那么拿map存有用的和没用的。。每个节点开个map即可。

    这样理论多个log还更快?

    # include <map>
    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 6e6 + 10, N = 310;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    char str[N];
    
    struct trienode {
        map<int, trienode*> ch;
        int w;
        vector<int> v;
    }T[M];
    int cnt = 1;
    
    int nQ;
    inline void add(char *str, int d) {
        trienode *p = &T[1], *q;
        for (int i=0, c; str[i]; ++i) {
            c = str[i] - 'a';
            if(p->ch[c] == 0) {
                ++cnt;
                q = &T[cnt];
                p->ch[c] = q;
            }
            p = p->ch[c];
            p->w += d;
            if((p->v).size() < p->w) p->v.push_back(nQ);
        }
    }
    
    inline int query(int d) {
    //    printf("d = %d
    ", d);
        trienode *p = &T[1], *q;
        for (int i=0, c; str[i]; ++i) {
            c = str[i] - 'a';
            if(p->ch[c] == 0) return -1;
            p = p->ch[c];
    //        printf("%d
    ", p->v.size());
        }
        if(p->v.size() > d) return p->v[d];
        else return -1;
    }
    
    
    int main() {
        int q, opt, a, b, c;
        cin >> q;
        int ans = 0;
        for (nQ = 1; nQ <= q; ++nQ) {
            scanf("%d", &opt); 
            scanf("%s", str);
            if(opt == 1) add(str, 1);
            else if(opt == 2) add(str, -1);
            else {
                scanf("%d%d%d", &a, &b, &c);
                ans = query(((ll)a*abs(ans)+b)%c);
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    View Code

    (下一个是用map,上一个是直接400w个trienode开26个ch)

  • 相关阅读:
    stm32 fatfs 文件系统分析和代码解析
    STM32 USB协议和代码分析
    微型跟踪器A产品体验和分析
    辅听一号产品体验和测评
    华为sound x智能音箱初体验
    TPC-H 分析
    论文解析 -- TPC-H Analyzed: Hidden Messages and Lessons Learned from an Influential Benchmark
    Calcite分析 -- Cost
    Calcite分析 -- ConverterRule
    Calcite分析 -- TopDownRuleDriver
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4896.html
Copyright © 2011-2022 走看看