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\n", 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

 

posted @ 2015-12-21 09:09  Showson  阅读(230)  评论(0编辑  收藏  举报