BZOJ3196——二逼平衡树
1、题目大意:给你一个序列,有5种操作,都有什么呢。。。
1> 区间第k小 这个直接用二分+树套树做
2> 区间小于k的有多少 这个直接用树套树做
3> 单点修改 这个直接用树套树做
4> 区间内k的前驱 这个就是1和2操作的合并,就是查询k的排名,然后就是知道他的前驱的排名,然后第k小
5> 区间内k的后继 这个和4同理
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; struct Node{ Node *ch[2]; int num, cnt, v, r; bool operator < (const Node& rhs) const{ return r < rhs.r; } inline int cmp(int x){ if(x == v) return -1; if(x < v) return 0; return 1; } inline void maintain(){ cnt = num; if(ch[0]) cnt += ch[0] -> cnt; if(ch[1]) cnt += ch[1] -> cnt; return; } } ft[5000000], *root[400000]; int tot; int a[100000]; inline void treap_rotate(Node* &o, int d){ Node *k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o; o -> maintain(); k -> maintain(); o = k; return; } inline void treap_insert(Node* &o, int value){ if(!o){ o = &ft[tot ++]; o -> ch[0] = o -> ch[1] = NULL; o -> num = 1; o -> v = value; o -> r = rand(); } else{ int d = o -> cmp(value); if(d == -1){ o -> num ++; } else{ treap_insert(o -> ch[d], value); if(o -> ch[d] > o) treap_rotate(o, d ^ 1); } } o -> maintain(); } inline void treap_remove(Node* &o, int value){ if(!o) return; int d = o -> cmp(value); if(d == -1){ if(o -> num > 1) o -> num --; else if(!o -> ch[0]) o = o -> ch[1]; else if(!o -> ch[1]) o = o -> ch[0]; else{ int d2; if(o -> ch[0] > o -> ch[1]) d2 = 1; else d2 = 0; treap_rotate(o, d2); treap_remove(o -> ch[d2], value); } } else{ treap_remove(o -> ch[d], value); } if(o) o -> maintain(); } inline int treap_lessk(Node* &o, int k){ if(!o) return 0; int d = o -> cmp(k); if(d == -1){ int ret = o -> num; if(o -> ch[0]) ret += o -> ch[0] -> cnt; return ret; } else if(d == 0){ return treap_lessk(o -> ch[d], k); } else{ int ss = o -> num; if(o -> ch[0]) ss += o -> ch[0] -> cnt; return treap_lessk(o -> ch[d], k) + ss; } } inline int treap_find(Node* &o, int k){ if(!o) return 0; int d = o -> cmp(k); if(d == -1) return o -> num; else return treap_find(o -> ch[d], k); } inline int segment_tree_find(int l, int r, int o, int x, int y, int k){ if(x <= l && r <= y){ return treap_find(root[o], k); } int mid = (l + r) / 2; int ret = 0; if(x <= mid) ret += segment_tree_find(l, mid, 2 * o, x, y, k); if(y > mid) ret += segment_tree_find(mid + 1, r, 2 * o + 1, x, y, k); return ret; } inline void segment_tree_add(int l, int r, int o, int x, int value){ treap_remove(root[o], a[x]); treap_insert(root[o], value); if(l == r){ a[x] = value; return; } int mid = (l + r) / 2; if(x <= mid) segment_tree_add(l, mid, 2 * o, x, value); else segment_tree_add(mid + 1, r, 2 * o + 1, x, value); } inline int segment_tree_query_lessk(int l, int r, int o, int x, int y, int k){ if(x <= l && r <= y){ return treap_lessk(root[o], k); } int mid = (l + r) / 2; int ret = 0; if(x <= mid) ret += segment_tree_query_lessk(l, mid, 2 * o, x, y, k); if(y > mid) ret += segment_tree_query_lessk(mid + 1, r, 2 * o + 1, x, y, k); return ret; } inline int segment_tree_query_NO_k(int l, int r, int o, int x, int y, int k, int n){ int L = 0, R = 100000000; while(L < R){ int mid = (L + R) / 2; if(segment_tree_query_lessk(1, n, 1, x, y, mid) < k) L = mid + 1; else R = mid; } return L; } int main(){ int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++){ int x; scanf("%d", &x); segment_tree_add(1, n, 1, i, x); } for(int i = 1; i <= m; i ++){ int op, x, y, z; scanf("%d", &op); if(op == 1){ scanf("%d%d%d", &x, &y, &z); int ans = segment_tree_query_lessk(1, n, 1, x, y, z); ans -= segment_tree_find(1, n, 1, x, y, z); ans ++; printf("%d\n", ans); } else if(op == 2){ scanf("%d%d%d", &x, &y, &z); int ans = segment_tree_query_NO_k(1, n, 1, x, y, z, n); printf("%d\n", ans); } else if(op == 3){ scanf("%d%d", &x, &y); segment_tree_add(1, n, 1, x, y); } else if(op == 4){ scanf("%d%d%d", &x, &y, &z); int k = segment_tree_query_lessk(1, n, 1, x, y, z); k -= segment_tree_find(1, n, 1, x, y, z); int ans = segment_tree_query_NO_k(1, n, 1, x, y, k, n); printf("%d\n", ans); } else{ scanf("%d%d%d", &x, &y, &z); int k = segment_tree_query_lessk(1, n, 1, x, y, z); k ++; int ans = segment_tree_query_NO_k(1, n, 1, x, y, k, n); printf("%d\n", ans); } } return 0; }
BZOJ3196——二逼平衡树的更多相关文章
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- bzoj3196 二逼平衡树 树状数组套线段树
题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...
- bzoj3196 二逼平衡树 树套树(线段树套Treap)
Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4697 Solved: 1798[Submit][Status][D ...
- bzoj3196 二逼平衡树
题目链接 平衡树系列最后一题 坑啊 10s时间限制跑了9764ms...还是要学一学bit套主席树啦... 经典的线段树套treap...至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了 ...
- BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)
我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...
- [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]
题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...
- BZOJ3196 二逼平衡树 【线段树套平衡树】
题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱 ...
- luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)
带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...
- BZOJ3196:二逼平衡树(线段树套Splay)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
随机推荐
- rdesktop in linux
rdesktop -f -a 16 -u administrator -p passwrod feelamcheung 192.168.0.2:8080
- easyUI文本框textbox笔记
知识点: 1.图标位置 Icon Align属性,有left和right两个: 2.textbox的setvalue方法,getvalue方法. <div style="margin: ...
- cmake 静态调用 c++ dll 的类的一个例子(Clion IDE)[更新1:增加1.模版的应用,2.ma 的算法]
CMakeLists.txt project(aaa) add_library(aaa SHARED aaa.cpp) add_executable(bbb bbb.cpp) target_link_ ...
- pc端,自适应屏幕分辨率
前端开发框架Bootstrap 网址:http://www.dnzs.com.cn/w3cschool/bootstrap/bootstrap-tutorial.html 需要加入代码 <sc ...
- 设计模式学习——策略模式(Strategy Pattern)
0. 前言 最近在重构公司的一个项目的时候,在抽取DES加密重复部分代码的时候,突然间想起了策略模式,感觉策略模式好像可以应用上,于是重新学习了下策略模式.注:在DES加密中,有DES和TDES算法, ...
- guid正则表达
a-fA-F0-9 加上下划线 _ 可以用 \w 来代替. ^\w{8}-(\w{4}-){3}\w{12}$ 如果不可以用下划线, 0-9 用 \d 代替 a-fA-F 就用其中一个 a-f,然后匹 ...
- 修改wampserver 默认localhost 和phpmyadmin 打开链接
在wamp上 左键打开localhost 自定义端口的话 或者其他网址 需要以下修改(同样访问phpmyadmin修改也是这个地方) 修改文件路径 D:\wamp\wampmanager.tpl 搜索 ...
- MVC缓存OutPutCache学习笔记 (二) 缓存及时化VaryByCustom
<MVC缓存OutPutCache学习笔记 (一) 参数配置> 本篇来介绍如何使用 VaryByCustom参数来实现缓存的及时化.. 根据数据改变来及时使客户端缓存过期并更新.. 首先更 ...
- .NET对象判等归纳与总结
1.引言 最近在看<CLR via C#>看到对象判等的那一节,觉得这也是.NET基础知识中比较重要的部分就写一篇博文来简单的总结归纳一下. 2..NET下的对象判等 在.NET中关于对象 ...
- linux环境下给文件加密/解密的方法
原文地址:linix环境下给文件加密/解密的方法 作者:oracunix 一. 利用 vim/vi 加密:优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了:缺点:很明显让别人知 ...