无聊来写了下

一开始发现树高是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. 环状DNA序列

    大意: 一个DNA序列是环状的,这意味着有N个碱基的序列有N种表示方法(假设无重复).而这N个序列有一种最小的表示,这个最小表示的意思是这个序列的字典序最小(字典序的意思是在字典中的大小 比如ABC& ...

  2. Mysql创建删除索引

    1.查看某个表中的索引 show index from 表名 2.为某个表创建索引 alter table 表名 add index 索引名(列名)    //此种方式创建一般的索引 alter ta ...

  3. Android Material Design NavigationView 及 Palette 颜色提取器

    DrawerLayout + NavigationView DrawerLayout布局,通常在里面添加两个子控件,程序主界面添加到NavitagionView前面. <android.supp ...

  4. jquery 左侧展开栏目

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. PHP实现中文字串截取无乱码的方法

    直接使用PHP函数substr截取中文字符可能会出现乱码,主要是substr可能硬生生的将一个中文字符“锯”成两半.解决办法: 1.使用mbstring扩展库的mb_substr截取就不会出现乱码了. ...

  6. 用MFC如何高效地绘图

    显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题.而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案.     MFC的绘图效率的确不高但也不差,而且它的绘图函数使用非常简单,只 ...

  7. Python 3中套接字编程中遇到TypeError: 'str' does not support the buffer interface的解决办法

    转自:http://blog.csdn.net/chuanchuan608/article/details/17915959 目前正在学习python,使用的工具为python3.2.3.发现3x版本 ...

  8. 什么是redis数据库?

    新公司的第一个项目让用redis.之前没接触过,所以从网上找些文章,学习理解一下   原链接:http://baike.so.com/doc/5063975-5291322.html 什么是redis ...

  9. iOS中的隐式动画

    隐式动画就是指  在 非 人为在代码中 定义动画  而系统却默认  自带   的动画  叫做隐式动画. 比如  改变 图层  的颜色  位置  和   透明度  的时候    都会  产生附带的渐变的 ...

  10. Seven Steps to Success Machine Learning in Practice

    Seven Steps to Success Machine Learning in Practice Project failures in IT are all too common. The r ...