• bzoj3065: 带插入区间K小值


    无聊来写了下

    一开始发现树高是O(n)的,然后就MLE了,进去看了下发现没有重构!

    看了半天发现调用错了函数

    然后进去又发现不满足sz = ch[0]->sz + ch[1]->sz + 1

    然而全都是maintain过的啊

    发现后来受某个代码的影响

    返回重建节点时把引用去掉了

    这样这个点的父亲的信息就不对了

    又仔细去看了一下那个人为什么这样做没问题

    结果他每次都把内存回收了,而且重建的根节点是最后删除第一个拿出来的(然后他竟然用的队列,当我什么都没说,我还是不知道为什么是对的。。)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6 //#include<cassert>
      7 
      8 using namespace std;
      9 
     10 #define ALL_VALUE 0, 70000
     11 const int N = 70000 + 10;
     12 
     13 int CNT1 = 0, CNT2 = 0;
     14 
     15 namespace ST {
     16     struct Node *stk[N * 60]; int top;
     17     struct Node {
     18         int sz;
     19         Node* ch[2];
     20         
     21         Node() {}
     22         Node(int sz) : sz(sz) {
     23             ch[0] = ch[1] = 0;
     24         }
     25         
     26         void *operator new (size_t) {
     27 //            if(!++CNT1 % 100000) cerr << CNT1 << endl;
     28             if(top) return stk[top--];
     29             static Node *pis;
     30             static int left = 0;
     31             if(!left) left = N, pis = new Node[N] ();
     32             return left--, pis++;
     33         }
     34         
     35         void operator delete(void *p) {
     36 //            ++CNT2;
     37             stk[++top] = (Node*) p;
     38         }
     39     };
     40     
     41     #define mid ((l + r) >> 1)
     42     #define ls o->ch[0], l, mid
     43     #define rs o->ch[1], mid + 1, r
     44     
     45     void insert(Node*& o, int l, int r, int v, int d) {
     46         if(!o) o = new Node(0);
     47         o->sz += d;
     48         if(l == r) return;
     49         if(v <= mid) insert(ls, v, d);
     50         else insert(rs, v, d);
     51         if(!o->sz) delete o, o = 0;
     52     }
     53     
     54     int query(Node* o, int l, int r, int v) {// <=v µÄÊýµÄ¸öÊý 
     55         if(!o) return 0;
     56         if(r <= v) return o->sz;
     57         return query(ls, v) + (v > mid ? query(rs, v) : 0);
     58     }
     59     
     60     void remove(Node*& o) {
     61         if(!o) return;
     62         remove(o->ch[0]);
     63         remove(o->ch[1]);
     64         delete o, o = 0;
     65     }
     66     
     67     #undef mid
     68     #undef ls
     69     #undef rs
     70 }
     71 
     72 int a[N], dep = 0;
     73 
     74 namespace SGT {
     75     struct Node *pis;
     76     struct Node {
     77         int sz, v;
     78         
     79         Node *ch[2];
     80         ST::Node *da;
     81         
     82         int cmp(int k) const {
     83             int s = ch[0]->size() + 1;
     84             if(s == k) return -1;
     85             return k < s ? 0 : 1;
     86         }
     87         
     88         Node(int v = 0) : v(v) {
     89             ch[0] = ch[1] = 0;
     90             da = 0;
     91             sz = 1;
     92         }
     93         
     94         int size() const {
     95             return this ? sz : 0;
     96         }
     97         
     98         void maintain() {
     99             sz = ch[0]->size() + ch[1]->size() + 1;
    100         }
    101         
    102         int query(int k, int v) const {//²éѯ1-kÀï <= vµÄÊýµÄÊýÁ¿
    103             if(!this || !k) return 0;
    104 //            cerr << ch[0]->size() << endl;
    105             if(ch[0]->size() >= k) return ch[0]->query(k, v);
    106             return (ch[0] ? ST::query(ch[0]->da, ALL_VALUE, v) : 0) + (this->v <= v) + ch[1]->query(k - ch[0]->size() - 1, v);
    107         }
    108         
    109         void *operator new(size_t) {
    110             return pis++;
    111         }
    112     }*null, *root, pool[N];
    113     
    114     Node *rec[N]; int tot;
    115     
    116     void print(Node *o) {
    117         if(!o) return;
    118         print(o->ch[0]);
    119         ST::remove(o->da);
    120         rec[++tot] = o;
    121         print(o->ch[1]);
    122     }
    123     
    124     /*void check(Node *o) {
    125         if(!o) return;
    126         assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
    127         check(o->ch[0]);
    128         check(o->ch[1]);
    129     }*/
    130     
    131     void rebuild(Node*& o, int l, int r) {
    132         if(l > r) return o = 0, void();
    133         int mid = (l + r) >> 1;
    134         o = rec[mid];
    135         for(int i = l; i <= r; i++) ST::insert(o->da, ALL_VALUE, rec[i]->v, 1);
    136         rebuild(o->ch[0], l, mid - 1);
    137         rebuild(o->ch[1], mid + 1, r);
    138         o->maintain();
    139 //        assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
    140     }
    141     
    142     void build(Node*& o, int l, int r) {
    143         if(l > r) return;
    144         int mid = (l + r) >> 1;
    145         o = new Node(a[mid]);
    146         for(int i = l; i <= r; i++) ST::insert(o->da, ALL_VALUE, a[i], 1);
    147         build(o->ch[0], l, mid - 1);
    148         build(o->ch[1], mid + 1, r);
    149         o->maintain();
    150     }
    151     
    152     Node*& insert(Node*& o, int k, int x) { // ÔÚµÚx¸öλÖúó²åÈëx 
    153         if(!o) {
    154             o = new Node(x);
    155             ST::insert(o->da, ALL_VALUE, x, 1);
    156             return null;
    157         }
    158 //        assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
    159         int d = o->ch[0]->size() >= k ? 0 : 1;
    160         if(d == 1) k -= o->ch[0]->size() + 1;
    161         Node*& res = insert(o->ch[d], k, x);
    162         o->maintain();
    163         ST::insert(o->da, ALL_VALUE, x, 1);
    164         if(o->ch[d]->size() > o->size() * 0.75) return o;
    165         else return res;
    166 //        assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
    167     }
    168     
    169     int modify(Node*& o, int k, int x) {
    170 //        assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
    171         int d = o->cmp(k), old;
    172         if(d == 1) k -= o->ch[0]->size() + 1;
    173         if(d == -1) old = o->v, o->v = x;
    174         else old = modify(o->ch[d], k, x);
    175         ST::insert(o->da, ALL_VALUE, old, -1);
    176         ST::insert(o->da, ALL_VALUE, x, 1);
    177         return old;
    178     }
    179     
    180     void insert(int k, int x) {
    181 //        SGT::check(SGT::root);
    182         Node*& res = insert(root, k, x);
    183 //        SGT::check(SGT::root);
    184         if(res != null) {
    185             tot = 0;
    186             print(res);
    187             rebuild(res, 1, tot);
    188 //            SGT::check(SGT::root);
    189         }
    190     }
    191 }
    192 
    193 int query(int l, int r, int k) {
    194     int L = 0, R = 70000, res = -1;
    195     while(L <= R) {
    196         int mid = (L + R) >> 1;
    197         int t1 = SGT::root->query(r, mid);
    198         int t2 = SGT::root->query(l - 1, mid);
    199         if(t1 - t2 >= k) R = mid - 1, res = mid;
    200         else L = mid + 1;
    201     }
    202     return res;
    203 }
    204 
    205 int main() {
    206 #ifdef DEBUG
    207     freopen("in.txt", "r", stdin);
    208     freopen("out.txt", "w", stdout);
    209 #endif
    210     
    211     SGT::pis = SGT::pool;
    212     
    213     int x, n, m;
    214     scanf("%d", &n);
    215     
    216     for(int i = 1; i <= n; i++) {
    217         scanf("%d", a + i);
    218     }
    219     
    220     int la = 0;
    221     
    222     SGT::build(SGT::root, 1, n);
    223     
    224     scanf("%d", &m);
    225     char opt[10]; int y, k, v;
    226     
    227     for(int i = 1; i <= m; i++) {
    228 //        if(i == 2859) 
    229 //        int debug = 1;
    230 //        SGT::check(SGT::root);
    231         
    232         scanf("%s", opt);
    233         if(opt[0] == 'Q') {
    234             scanf("%d%d%d", &x, &y, &k);
    235             x ^= la, y ^= la, k ^= la;
    236             printf("%d
    ", query(x, y, k));
    237         }else if(opt[0] == 'M') {
    238             scanf("%d%d", &x, &v);
    239             x ^= la, v ^= la;
    240             SGT::modify(SGT::root, x, v);
    241         }else {
    242             scanf("%d%d", &x, &v);
    243             x ^= la, v ^= la;
    244 //            int last = CNT1; dep = 0;
    245             SGT::insert(x - 1, v);
    246 //            cerr << SGT::root->sz << endl;
    247 //            cerr << CNT1 - last << ' ' << dep << endl;
    248         }
    249     }
    250     
    251     return 0;
    252 }
    View Code
  • 相关阅读:
    elk2
    elk
    skywalking学习ppt
    Spring Boot]SpringBoot四大神器之Actuator
    黑马程序员spring data jpa 2019年第一版本
    css总结7:盒子模型理解
    css总结5:px、em、rem区别介绍
    css总结4:input 去掉外边框,placeholder的字体颜色、字号
    css总结3:Flex 布局教程:Flex-demos(转)
    css总结2:Flex 布局教程:Flex 语法(转)
  • 原文地址:https://www.cnblogs.com/showson/p/5062449.html
Copyright © 2020-2023  润新知