之前写线段树套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. SPOJ - HIGH :Highways (生成树计数)

    Highways 题目链接:https://vjudge.net/problem/SPOJ-HIGH Description: In some countries building highways ...

  2. UVA 1645 Count

    https://vjudge.net/problem/UVA-1645 题意:有多少个n个节点的有根树,每个深度中所有节点的子节点数相同 dp[i] 节点数为i时的答案 除去根节点还有i-1个点,如果 ...

  3. Ant打jar包时,参数名被修改的问题

    https://blog.csdn.net/landehuxi/article/details/42678117 使用Ant打jar包后,发现jar包中的方法名会在前面自动添加了“param”前缀,导 ...

  4. [cerc2012][Gym100624B]20181013

  5. 【TYVJ】P1038 忠诚

    [算法]线段树 #include<cstdio> #include<algorithm> using namespace std; ]; ,inf=0x3f3f3f3f; in ...

  6. webpack自动化构建你的项目

    1.读万卷书,行万里路. 2.书山有路勤为径,学海无涯苦作舟. 技术段: 相信很多刚接触前端的小伙伴,对一些自动化工具会感觉无可下手.现在前端的发展的势头,势必和后台形成一个对立面,独挡一面. 这篇文 ...

  7. 生成应用的快捷方式action,权限

    action:"com.android.launcher.action.INSTALL_SHORTCUT" 权限:com.android.launcher.permission.I ...

  8. 转 Wireshark和TcpDump抓包分析心得

    1. Wireshark与tcpdump介绍 Wireshark是一个网络协议检测工具,支持Windows平台和Unix平台,我一般只在Windows平台下使用Wireshark,如果是Linux的话 ...

  9. perl HTML::LinkExtor模块(2)

    use LWP::Simple; use HTML::LinkExtor; $html_code = get("https://tieba.baidu.com/p/4929234512&qu ...

  10. Reactor与Proactor区别

    如网络编程中accept之后等待数据到达,并且读取数据为例: Reactor: 基于同步IO 1. 线程等待读取socket数据,将socketfd添加到事件分派器中,如添加到epoll: 2. 事件 ...