无聊来写了下

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

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

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

然而全都是maintain过的啊

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

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

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

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

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

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
//#include<cassert> using namespace std; #define ALL_VALUE 0, 70000
const int N = + ; int CNT1 = , CNT2 = ; namespace ST {
struct Node *stk[N * ]; int top;
struct Node {
int sz;
Node* ch[]; Node() {}
Node(int sz) : sz(sz) {
ch[] = ch[] = ;
} void *operator new (size_t) {
// if(!++CNT1 % 100000) cerr << CNT1 << endl;
if(top) return stk[top--];
static Node *pis;
static int left = ;
if(!left) left = N, pis = new Node[N] ();
return left--, pis++;
} void operator delete(void *p) {
// ++CNT2;
stk[++top] = (Node*) p;
}
}; #define mid ((l + r) >> 1)
#define ls o->ch[0], l, mid
#define rs o->ch[1], mid + 1, r void insert(Node*& o, int l, int r, int v, int d) {
if(!o) o = new Node();
o->sz += d;
if(l == r) return;
if(v <= mid) insert(ls, v, d);
else insert(rs, v, d);
if(!o->sz) delete o, o = ;
} int query(Node* o, int l, int r, int v) {// <=v µÄÊýµÄ¸öÊý
if(!o) return ;
if(r <= v) return o->sz;
return query(ls, v) + (v > mid ? query(rs, v) : );
} void remove(Node*& o) {
if(!o) return;
remove(o->ch[]);
remove(o->ch[]);
delete o, o = ;
} #undef mid
#undef ls
#undef rs
} int a[N], dep = ; namespace SGT {
struct Node *pis;
struct Node {
int sz, v; Node *ch[];
ST::Node *da; int cmp(int k) const {
int s = ch[]->size() + ;
if(s == k) return -;
return k < s ? : ;
} Node(int v = ) : v(v) {
ch[] = ch[] = ;
da = ;
sz = ;
} int size() const {
return this ? sz : ;
} void maintain() {
sz = ch[]->size() + ch[]->size() + ;
} int query(int k, int v) const {//²éѯ1-kÀï <= vµÄÊýµÄÊýÁ¿
if(!this || !k) return ;
// cerr << ch[0]->size() << endl;
if(ch[]->size() >= k) return ch[]->query(k, v);
return (ch[] ? ST::query(ch[]->da, ALL_VALUE, v) : ) + (this->v <= v) + ch[]->query(k - ch[]->size() - , v);
} void *operator new(size_t) {
return pis++;
}
}*null, *root, pool[N]; Node *rec[N]; int tot; void print(Node *o) {
if(!o) return;
print(o->ch[]);
ST::remove(o->da);
rec[++tot] = o;
print(o->ch[]);
} /*void check(Node *o) {
if(!o) return;
assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
check(o->ch[0]);
check(o->ch[1]);
}*/ void rebuild(Node*& o, int l, int r) {
if(l > r) return o = , void();
int mid = (l + r) >> ;
o = rec[mid];
for(int i = l; i <= r; i++) ST::insert(o->da, ALL_VALUE, rec[i]->v, );
rebuild(o->ch[], l, mid - );
rebuild(o->ch[], mid + , r);
o->maintain();
// assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
} void build(Node*& o, int l, int r) {
if(l > r) return;
int mid = (l + r) >> ;
o = new Node(a[mid]);
for(int i = l; i <= r; i++) ST::insert(o->da, ALL_VALUE, a[i], );
build(o->ch[], l, mid - );
build(o->ch[], mid + , r);
o->maintain();
} Node*& insert(Node*& o, int k, int x) { // ÔÚµÚx¸öλÖúó²åÈëx
if(!o) {
o = new Node(x);
ST::insert(o->da, ALL_VALUE, x, );
return null;
}
// assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
int d = o->ch[]->size() >= k ? : ;
if(d == ) k -= o->ch[]->size() + ;
Node*& res = insert(o->ch[d], k, x);
o->maintain();
ST::insert(o->da, ALL_VALUE, x, );
if(o->ch[d]->size() > o->size() * 0.75) return o;
else return res;
// assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
} int modify(Node*& o, int k, int x) {
// assert(o->sz == o->ch[0]->size() + o->ch[1]->size() + 1);
int d = o->cmp(k), old;
if(d == ) k -= o->ch[]->size() + ;
if(d == -) old = o->v, o->v = x;
else old = modify(o->ch[d], k, x);
ST::insert(o->da, ALL_VALUE, old, -);
ST::insert(o->da, ALL_VALUE, x, );
return old;
} void insert(int k, int x) {
// SGT::check(SGT::root);
Node*& res = insert(root, k, x);
// SGT::check(SGT::root);
if(res != null) {
tot = ;
print(res);
rebuild(res, , tot);
// SGT::check(SGT::root);
}
}
} int query(int l, int r, int k) {
int L = , R = , res = -;
while(L <= R) {
int mid = (L + R) >> ;
int t1 = SGT::root->query(r, mid);
int t2 = SGT::root->query(l - , mid);
if(t1 - t2 >= k) R = mid - , res = mid;
else L = mid + ;
}
return res;
} int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif SGT::pis = SGT::pool; int x, n, m;
scanf("%d", &n); for(int i = ; i <= n; i++) {
scanf("%d", a + i);
} int la = ; SGT::build(SGT::root, , n); scanf("%d", &m);
char opt[]; int y, k, v; for(int i = ; i <= m; i++) {
// if(i == 2859)
// int debug = 1;
// SGT::check(SGT::root); scanf("%s", opt);
if(opt[] == 'Q') {
scanf("%d%d%d", &x, &y, &k);
x ^= la, y ^= la, k ^= la;
printf("%d\n", query(x, y, k));
}else if(opt[] == 'M') {
scanf("%d%d", &x, &v);
x ^= la, v ^= la;
SGT::modify(SGT::root, x, v);
}else {
scanf("%d%d", &x, &v);
x ^= la, v ^= la;
// int last = CNT1; dep = 0;
SGT::insert(x - , v);
// cerr << SGT::root->sz << endl;
// cerr << CNT1 - last << ' ' << dep << endl;
}
} return ;
}

bzoj3065: 带插入区间K小值的更多相关文章

  1. [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树

    刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...

  2. BZOJ3065 带插入区间K小值 || 洛谷P4278

    这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...

  3. 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值

    显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...

  4. 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树

    [BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...

  5. bzoj 3065: 带插入区间K小值 替罪羊树 && AC300

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Des ...

  6. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  7. 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树

    经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...

  8. BZOJ 3065 带插入区间K小值(sag套线段树)

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 4696  Solved: 1527[Submit][Status][Di ...

  9. 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值

    常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...

随机推荐

  1. 回退符\b

    回退符\b #include <stdio.h> int main(){ printf("hello\b"); getchar(); getchar(); ; } 实验 ...

  2. 插入标记 方法 insertAdjacentHTML

    html5新增的插入标记方法,insertAdjacentHTML() 可以接受2个参数 插入位置和要插入的 HTML 文本.第一个参数必须是下列值之一: "beforebegin" ...

  3. 零售POS开发

    零售POS系统是一款基于离线与在线两种模式的POS系统,能够将门店的销售数据及时准确的同步到企业服务器.离线模式操作更加快捷.稳定.高效:在线操作实时同步会员信息.查看库存.下载最新档案.公文公告等一 ...

  4. 新增的output元素 progress元素 meter元素 keygen元素

    结果图 <output>是双标签 name:定义对象的唯一属性 for:定义输出域相关的一个或多个元素. form:定义所属的一个至多个表单. progress和meter一般和JS一起使 ...

  5. 1、C# MVC学习之NVelocity基本使用

    小白一个,刚刚开始学,大神不要笑话...... NVelocity是一个很容易上手的框架,从它开始学习,可以循序渐进 首先,创建空web应用程序,新建一般处理程序 Login2.ashx 然后,引入N ...

  6. css3实现无缝滚动效果

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. css3实现钟表特效

    <!doctype html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. bzoj 2209: [Jsoi2011]括号序列 splay

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 833  Solved: 392[Submit][Status ...

  9. 小游戏 Lights Out (关灯) 的求解 —— 异或方程组

    Author : Evensgn  Blog Link : http://www.cnblogs.com/JoeFan/ Article Link : http://www.cnblogs.com/J ...

  10. ExecutorService介绍

    转自: http://victorzhzh.iteye.com/blog/1010359 下面是excutor相关的类结果: ExecutorService接口继承了Executor接口,定义了一些生 ...