之前写线段树套splay数组版。。写了6.2k。。然后弃疗了。现在发现还是很水的。。嘎嘎。。

zju过不了,超时。

  upd:才发现zju是多组数据。。TLE一版才发现。然后改了,MLE。。。手写内存池。。尼玛终于过了。。附zju2112代码于后。

bzoj倒是过了,1A的感觉还是很爽的。。可是时间不好看。。这就是所谓\(O(nlog^3n)\)的复杂度的可怜之处么?

写挂的地方:

  • insert一定要是传地址指针进去。
  • delete时先把地址指针delete掉,最后把是地址指针指向左儿子or右儿子or NULL。
  • 节点初始化时一定要把左右儿子指针指向NULL。
  • 注意脑残,b打错变量名的问题。

做法:线段树约束区间,平衡树支持修改和查询,没了。

  修改:每次在包含点的线段树节点所包含的平衡树中删除要改的节点值,在插入新的值,\(O(log^2n)\)。

  查询:由于无法直接查询,所以二分答案,求得答案在区间內的排名,等于各区间小于该值的节点数量,select直接搞,总共\(O(log^3n)\),具体可以先插入一个值节点,在求值节点的rank,最后删掉即可。

我是用线段树套treap。

然后树状数组套平衡树也可以过,常数小很多。。。

达成成就:AC树套树。

 #include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
typedef long long LL;
const int maxn = + ;
int n, m, sum, a[maxn], INF = 0x3f3f3f3f;
struct treap_node {
treap_node *ch[];
int key, fix, cnt, size;
treap_node() {
ch[] = ch[] = NULL;
}
treap_node(int _key) {
ch[] = ch[] = NULL;
key = _key;
size = cnt = ;
fix = rand();
}
} *T[maxn << ];
inline void maintain(treap_node *t) {
t->size = t->cnt;
if(t->ch[]) t->size += t->ch[]->size;
if(t->ch[]) t->size += t->ch[]->size;
}
void rot(treap_node *&t, int d) {
treap_node *p = t->ch[d ^ ];
t->ch[d ^ ] = p->ch[d], p->ch[d] = t;
maintain(t), maintain(p);
t = p;
}
void insert(treap_node *&t, int val) {
if(t == NULL) {
t = new treap_node(val);
} else {
if(val < t->key) {
insert(t->ch[], val);
if(t->ch[]->fix < t->fix) rot(t, );
} else if(t->key < val) {
insert(t->ch[], val);
if(t->ch[]->fix < t->fix) rot(t, );
} else
++t->cnt;
}
maintain(t);
}
void del(treap_node *&t, int val) {
if(t->key == val) {
if(t->cnt == ) {
if(!t->ch[] || !t->ch[]) {
treap_node *p = t;
if(!p->ch[]) p = t->ch[];
else p = t->ch[];
delete t;
t = p;
} else {
int d = t->ch[]->fix < t->ch[]->fix;
rot(t, d);
del(t->ch[d], val);
}
} else --t->cnt;
} else del(t->ch[t->key < val], val);
if(t) maintain(t);
}
int select(treap_node *t, int val) {
if(t == NULL) return ;
if(val < t->key) return select(t->ch[], val);
int p = (t->ch[]) ? t->ch[]->size + t->cnt : t->cnt;
if(t->key < val) p += select(t->ch[], val);
return p;
}
bool ok;
void query(int l, int r, int rt, int ql, int qr, int val) {
if(ql <= l && r <= qr) {
sum += select(T[rt], val);
return ;
} else {
int mid = (l + r) >> ;
if(ql <= mid) query(l, mid, rt << , ql, qr, val);
if(mid < qr) query(mid + , r, rt << | , ql, qr, val);
}
}
void seg_del(int l, int r, int rt, int pos, int val) {
del(T[rt], val);
if(l == r) return ;
int mid = (l + r) >> ;
if(pos <= mid) seg_del(l, mid, rt << , pos, val);
else if(mid < pos) seg_del(mid + , r, rt << | , pos, val);
}
void seg_insert(int l, int r, int rt, int pos, int val) {
insert(T[rt], val);
if(l == r) return ;
int mid = (l + r) >> ;
if(pos <= mid) seg_insert(l, mid, rt << , pos, val);
else if(mid < pos) seg_insert(mid + , r, rt << | , pos, val);
} char gchar() {
char ret = getchar();
for(; ret == '\n' || ret == '\r' || ret == ' '; ret = getchar());
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin), freopen("data.out", "w", stdout);
#endif
scanf("%d%d", &n, &m);
srand(n * m + );
for(int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
seg_insert(, n, , i, a[i]);
}
ok = false;
for(int i = , p, b, c, d; i <= m; ++i) {
d = gchar();
if(d == 'C') {
scanf("%d%d", &p, &b);
seg_del(, n, , p, a[p]);
a[p] = b;
seg_insert(, n, , p, a[p]);
} else {
scanf("%d%d%d", &b, &c, &p);
LL l = , r = INF;
while(l < r) {
LL mid = (l + r) >> ;
sum = ;
query(, n, , b, c, mid);
if(sum < p) {
l = mid + ;
} else {
r = mid;
}
}
printf("%lld\n", l);
}
}
return ;
}
 #include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
typedef long long LL;
const int maxn = + ;
int n, m, sum, a[maxn], INF = 0x3f3f3f3f;
struct treap_node {
treap_node *ch[];
int key, fix, cnt, size;
treap_node() {
ch[] = ch[] = NULL;
}
treap_node(int _key) {
ch[] = ch[] = NULL;
key = _key;
size = cnt = ;
fix = rand();
}
} *T[maxn << ];
treap_node null_thing;
struct storage {
treap_node free_node[maxn * ];
int top, rec;
void init() {
rec = maxn * ;
for(int i = ; i < rec; ++i) free_node[top++] = i;
}
treap_node _new(int val) {
return free_node[--top] = treap_node(val);
}
void back_data() {
for(int i = top; i < rec; ++i) free_node[top++] = i;
}
}S; inline void maintain(treap_node *t) {
t->size = t->cnt;
if(t->ch[]) t->size += t->ch[]->size;
if(t->ch[]) t->size += t->ch[]->size;
}
void rot(treap_node *&t, int d) {
treap_node *p = t->ch[d ^ ];
t->ch[d ^ ] = p->ch[d], p->ch[d] = t;
maintain(t), maintain(p);
t = p;
}
void insert(treap_node *&t, int val) {
if(t == NULL) {
S._new(val);
t = &S.free_node[S.top];
} else {
if(val < t->key) {
insert(t->ch[], val);
if(t->ch[]->fix < t->fix) rot(t, );
} else if(t->key < val) {
insert(t->ch[], val);
if(t->ch[]->fix < t->fix) rot(t, );
} else
++t->cnt;
}
maintain(t);
}
void del(treap_node *&t, int val) {
if(t->key == val) {
if(t->cnt == ) {
if(!t->ch[] || !t->ch[]) {
treap_node *p = t;
if(!p->ch[]) p = t->ch[];
else p = t->ch[];
t = p;
} else {
int d = t->ch[]->fix < t->ch[]->fix;
rot(t, d);
del(t->ch[d], val);
}
} else --t->cnt;
} else del(t->ch[t->key < val], val);
if(t) maintain(t);
}
int select(treap_node *t, int val) {
if(t == NULL) return ;
if(val < t->key) return select(t->ch[], val);
int p = (t->ch[]) ? t->ch[]->size + t->cnt : t->cnt;
if(t->key < val) p += select(t->ch[], val);
return p;
}
bool ok;
void query(int l, int r, int rt, int ql, int qr, int val) {
if(ql <= l && r <= qr) {
sum += select(T[rt], val);
return ;
} else {
int mid = (l + r) >> ;
if(ql <= mid) query(l, mid, rt << , ql, qr, val);
if(mid < qr) query(mid + , r, rt << | , ql, qr, val);
}
}
void seg_del(int l, int r, int rt, int pos, int val) {
del(T[rt], val);
if(l == r) return ;
int mid = (l + r) >> ;
if(pos <= mid) seg_del(l, mid, rt << , pos, val);
else if(mid < pos) seg_del(mid + , r, rt << | , pos, val);
}
void seg_insert(int l, int r, int rt, int pos, int val) {
insert(T[rt], val);
if(l == r) return ;
int mid = (l + r) >> ;
if(pos <= mid) seg_insert(l, mid, rt << , pos, val);
else if(mid < pos) seg_insert(mid + , r, rt << | , pos, val);
} char gchar() {
char ret = getchar();
for(; ret == '\n' || ret == '\r' || ret == ' '; ret = getchar());
return ret;
}
void del_tree(int l, int r, int rt) {
T[rt] = NULL;
if(l == r) return ;
int mid = (l + r) >> ;
del_tree(l, mid, rt << );
del_tree(mid + , r, rt << | );
}
int main() { int test_num;
scanf("%d", &test_num);
S.init();
while(test_num--) {
S.back_data();
scanf("%d%d", &n, &m);
del_tree(, n, );
srand(n * m + );
for(int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
seg_insert(, n, , i, a[i]);
}
ok = false;
for(int i = , p, b, c, d; i <= m; ++i) {
d = gchar();
if(d == 'C') {
scanf("%d%d", &p, &b);
seg_del(, n, , p, a[p]);
a[p] = b;
seg_insert(, n, , p, a[p]);
} else {
scanf("%d%d%d", &b, &c, &p);
LL l = , r = INF;
while(l < r) {
LL mid = (l + r) >> ;
sum = ;
query(, n, , b, c, mid);
if(sum < p) {
l = mid + ;
} else {
r = mid;
}
}
printf("%lld\n", l);
}
}
}
return ;
}

zju 2112

BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树的更多相关文章

  1. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  2. bzoj 1901: Zju2112 Dynamic Rankings(树套树)

    1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...

  3. BZOJ 1901 Zju2112 Dynamic Rankings

    树阵主席设置树.维护间隔动态K大. .. ZOJ到空间太小,太大,仅仅能到BZOJ上交 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memor ...

  4. BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7143  Solved: 2968[Su ...

  5. Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6471  Solved: 2697[Su ...

  6. Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6321  Solved: 2628[Su ...

  7. bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

  8. BZOJ 1901: Zju2112 Dynamic Rankings( 树状数组套主席树 )

    裸的带修改主席树.. 之前用BIT套Splay( http://www.cnblogs.com/JSZX11556/p/4625552.html )A过..但是还是线段树好写...而且快(常数比平衡树 ...

  9. BZOJ 1901: Zju2112 Dynamic Rankings( BIT 套 BST )

    BIT 套 splay 其实也是不难...每个 BIT 的结点保存一颗 splay , 询问就二分答案然后判断rank... ------------------------------------- ...

随机推荐

  1. Linux下 ps -ef 和 ps aux 的区别及格式详解

    原文:https://www.cnblogs.com/5201351/p/4206461.html Linux下ps -ef和ps aux的区别及格式详解 Linux下显示系统进程的命令ps,最常用的 ...

  2. pc扫码支付

    https://www.cnblogs.com/shengyu-kmust/p/5228261.html https://pay.weixin.qq.com/wiki/doc/api/native.p ...

  3. Spring实战第一部分总结

                                                         Spring实战第一部分总结 第一章 综述 1. DI依赖注入让相互协作的组件保持松散耦合,而 ...

  4. jquery checkbox选中状态以及实现全选反选

    jquery1.6以下版本获取checkbox的选中状态: $('.ck').attr('checked'); $('.ck').attr('checked',true);//全选 $('.ck'). ...

  5. rsync的命令参数【转】

    本篇文章,我们只介绍rsync的命令参数. rsync参数的具体解释如下: -v, –verbose 详细模式输出 -q, –quiet 精简输出模式 -c, –checksum 打开校验开关,强制对 ...

  6. 用reduce实现简单的pipe

    function pipe(src, ...fns){ return fns.reduce(function(fn1, fn2){ return fn2(fn1) }, src); } undefin ...

  7. 【NOIP】2016 换教室

    [算法]期望DP+floyd [题解]用floyd预处理最短距离. 注意重边与自环——图论双毒!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! QAQ 然后搞清楚方案和概率的问 ...

  8. [Unity]插件Node Editor介绍 实现类似状态机画布的扩展

    Unity自带的动画状态机有一套对策划非常友好的UI.但是Unity官方没有公开这些控件的api.除了Asset Store里一些已有的方案,我在这里介绍一个在github上的开源项目,封装了底层,但 ...

  9. 往Layout中动态添加View

    需要注意几个方法:基本上所有的方法参数单位是px 1.设置View的宽高: LinearLayout.LayoutParams params = new LinearLayout().LayoutPa ...

  10. 集合框架源码学习之LinkedList

    0-1. 简介 0-2. 内部结构分析 0-3. LinkedList源码分析 0-3-1. 构造方法 0-3-2. 添加add方法 0-3-3. 根据位置取数据的方法 0-3-4. 根据对象得到索引 ...