• BZOJ 3685: 普通van Emde Boas树( 线段树 )


    建颗权值线段树就行了...连离散化都不用...

    没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... 

    ------------------------------------------------------------------------------------------

    #include<bits/stdc++.h>
       
    #define rep(i, n) for(int i = 0; i < n; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define M(l, r) (((l) + (r)) >> 1)
     
    using namespace std;
     
    const int maxn = 1000009; 
     
    struct Node {
    Node *l, *r;
    bool s;
    Node() {
    s = false;
    }
    inline void update() {
    s = l->s || r->s;
    }
    } pool[maxn << 1], *pt = pool, *root;
     
    void build(Node* t, int l, int r) {
    if(r > l) {
    int m = M(l, r);
    build(t->l = pt++, l, m);
    build(t->r = pt++, m + 1, r);
    }
    }
     
    int n, v, type;
     
    void modify(Node* t, int l, int r) {
    if(l == r) {
    if(type == 1 && !t->s) t->s = true;
    if(type == 2 && t->s) t->s = false;
    } else {
    int m = M(l, r);
    v <= m ? modify(t->l, l, m) : modify(t->r, m + 1, r);
    t->update();
    }
    }
     
    int query(Node* t, int l, int r) {
    if(!t->s) return 0;
    if(l == r) return l;
    int m = M(l, r);
    return type == 3 ? (t->l->s ? query(t->l, l, m) : query(t->r, m + 1, r)) : 
                      (t->r->s ? query(t->r, m + 1, r) : query(t->l, l, m));
    }
     
    int succ(Node* t, int l, int r) {
    if(!t->s) return 0;
    if(l == r) return l <= v ? 0 : l;
    int m = M(l, r);
    if(v >= m) return succ(t->r, m + 1, r);
    int ans = succ(t->l, l, m);
    return ans ? ans : succ(t->r, m + 1, r);
    }
     
    int pred(Node* t, int l, int r) {
    if(!t->s) return 0;
    if(l == r) return l >= v ? 0 : l;
    int m = M(l, r);
    if(m + 1 >= v) return pred(t->l, l, m);
    int ans = pred(t->r, m + 1, r);
    return ans ? ans : pred(t->l, l, m);
    }
     
    int find(Node* t, int l, int r) {
    if(!t->s) return -1;
    if(l == r) return 1;
    int m = M(l, r);
    return v <= m ? find(t->l, l, m) : find(t->r, m + 1, r);
    }
     
    inline void read(int &t) {
    t = 0;
    char c = getchar();
    for(; !isdigit(c); c = getchar());
    for(; isdigit(c); c = getchar())
       t = t * 10 + c - '0';
    }
     
    int main() {
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
    int m;
    cin >> n >> m;
    n++;
    build(root = pt++, 1, n);
    while(m--) {
    read(type);
    switch(type) {
    case 1 : read(v); v++; modify(root, 1, n); break;
    case 2 : read(v); v++; modify(root, 1, n); break;
    case 3 : printf("%d ", query(root, 1, n) - 1); break;
    case 4 : printf("%d ", query(root, 1, n) - 1); break;
    case 5 : read(v); v++; printf("%d ", pred(root, 1, n) - 1); break;
    case 6 : read(v); v++; printf("%d ", succ(root, 1, n) - 1); break;
    case 7 : read(v); v++; printf("%d ", find(root, 1, n)); break;
    default : break;
    }
    }
    return 0;
    }

    ------------------------------------------------------------------------------------------ 

    3685: 普通van Emde Boas树

    Time Limit: 9 Sec  Memory Limit: 128 MB
    Submit: 616  Solved: 216
    [Submit][Status][Discuss]

    Description

    设计数据结构支持:
    1 x  若x不存在,插入x
    2 x  若x存在,删除x
    3    输出当前最小值,若不存在输出-1
    4    输出当前最大值,若不存在输出-1
    5 x  输出x的前驱,若不存在输出-1
    6 x  输出x的后继,若不存在输出-1
    7 x  若x存在,输出1,否则输出-1

    Input

    第一行给出n,m 表示出现数的范围和操作个数
    接下来m行给出操作
    n<=10^6,m<=2*10^6,0<=x<n

    Output

    Sample Input

    10 11
    1 1
    1 2
    1 3
    7 1
    7 4
    2 1
    3
    2 3
    4
    5 3
    6 2


    Sample Output

    1
    -1
    2
    2
    2
    -1

    HINT

    Source

  • 相关阅读:
    学Linux从编译命令开始——arm-linux-gcc常用参数讲解
    暑假计划
    汇编语言
    “&”详解
    密码和密钥的区别
    有关动态库找不到的问题解决方案
    gdb调试基本命令(常用)
    Makefile相关知识
    有关宏定义的bug
    Linux安装时内存如何分区的相关问题
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4666047.html
Copyright © 2020-2023  润新知