• 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)

  • 相关阅读:
    安卓客户端获取手机号码
    安卓自定义控件之设计自己的提示dialog
    一步步打造自己的分页控件4
    C#winform小游戏之贪吃蛇重温C#
    android观察者模式
    Android开发之Java设计模式
    Android 用Animationlist实现逐帧动画
    图片压缩
    Android使用缓存优化ListView
    Android命令行启动程序正确使用技巧解析
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4896.html
Copyright © 2020-2023  润新知