Bzoj 3196 Tyvj 1730 二逼平衡树
3196: Tyvj 1730 二逼平衡树
>原题链接<
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)
Input
第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继
Output
对于操作1,2,4,5各输出一行,表示查询结果
Sample Input
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5
Sample Output
4
3
4
9
思路:
这种题就不需要思路了吧,我几乎是写了一个最麻烦的线段树套Treap(比较经典的树套树),几位机房大佬有写不到100行的树状数组套主席树>这里<
上一下代码,留待日后温习:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#define ls p<<1
#define rs p<<1|1
#define O2 __attribute__((optimize("-O2")))
using namespace std;
const int inf = 2147483647;
const int N = 51000;
const int M = 2000010;
int n, m;
int a[N];
class ReadIn {private:O2 inline char nc() {static char buf[100000], *p1, *p2;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}public:O2 inline int Read() {int x=0,f=1;char ch=nc();while(!isdigit(ch)){if(ch=='-')f=-1;ch=nc();};while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=nc();}return x*f;}O2 inline char getc() {char ch=nc();while(isspace(ch))ch=nc();return ch;}
}Rd;
class Treap {int cnt;struct Tree {int siz,key,val,v;int s[2];}Tr[M];
private:O2 int Build(int x) {cnt++;Tr[cnt].key = rand();Tr[cnt].val = x;Tr[cnt].siz = 1;Tr[cnt].v = 1;Tr[cnt].s[0] = Tr[cnt].s[1] = 0;return cnt;}O2 void Update(int x) {Tr[x].siz = Tr[x].v + Tr[Tr[x].s[0]].siz + Tr[Tr[x].s[1]].siz ;}O2 void Rotate(int &x,int i) {int p = Tr[x].s[i];Tr[x].s[i] = Tr[p].s[i^1];Tr[p].s[i^1] = x;Update(x);Update(p);x = p;}
public:O2 void Insert(int &p, int k) {if(!p) {p=Build(k);}else if(Tr[p].val==k) {Tr[p].v++;}else {if(Tr[p].val<k) {Insert(Tr[p].s[1], k);if(Tr[Tr[p].s[1]].key>Tr[p].key) {Rotate(p, 1);}}else {Insert(Tr[p].s[0], k);if(Tr[Tr[p].s[0]].key > Tr[p].key) {Rotate(p, 0);}}}Update(p);}O2 void Del(int &p, int k) {if(Tr[p].val < k) {Del(Tr[p].s[1],k);}else if(Tr[p].val > k) {Del(Tr[p].s[0],k);}else {if(Tr[p].v > 1) {Tr[p].v -- ;}else {if(Tr[p].s[0]*Tr[p].s[1] == 0) {p = Tr[p].s[0] + Tr[p].s[1];}else {if(Tr[Tr[p].s[0]].key > Tr[Tr[p].s[1]].key) {Rotate(p, 0);Del(Tr[p].s[1], k);}else {Rotate(p, 1);Del(Tr[p].s[0], k);}}}}if(p) {Update(p);}}O2 int Rank(int p, int k) {if(!p) {return 0;}if(Tr[p].val > k) {return Rank(Tr[p].s[0], k);}else if(Tr[p].val < k) {return Rank(Tr[p].s[1],k) + Tr[Tr[p].s[0]].siz + Tr[p].v;}else {return Tr[Tr[p].s[0]].siz;}}O2 int Pre(int p, int k) {if(!p) {return -inf;}if(Tr[p].val >= k) {return Pre(Tr[p].s[0], k);}else {return max(Tr[p].val,Pre(Tr[p].s[1],k));}}O2 int Suc(int p, int k) {if(!p) {return inf;}if(Tr[p].val <= k) {return Suc(Tr[p].s[1], k);}else {return min(Tr[p].val,Suc(Tr[p].s[0],k));}}}Trp;
class SegmentTree {
private:struct Tree {int l, r, root;int minn;}Tr[M];O2 void Build(int l,int r,int p) {Tr[p].l = l;Tr[p].r = r;int i;for(i=l;i<=r;i++) {Trp.Insert(Tr[p].root, a[i]);}if(l==r) {Tr[p].minn=a[l];return ;}if(l!=r) {int mid = (l+r) >> 1;Build(l,mid,ls);Build(mid+1,r,rs);}Tr[p].minn=min(Tr[ls].minn,Tr[rs].minn);}O2 void Change(int p, int x, int c) {Trp.Del(Tr[p].root,a[x]);Trp.Insert(Tr[p].root,c);int &l = Tr[p].l, &r = Tr[p].r;if(l==r) {Tr[p].minn=c;return;}int mid = (l+r) >> 1;if(x<=mid) {Change(ls, x, c);}else {Change(rs, x, c);}Tr[p].minn=min(Tr[ls].minn,Tr[rs].minn);}O2 int Pre(int l, int r, int p, int k) {int &ll = Tr[p].l, &rr = Tr[p].r;if(ll>r||rr<l) {return -inf;}if(ll>=l&&rr<=r) {return Trp.Pre(Tr[p].root,k);}else {return max(Pre(l, r, ls, k), Pre(l, r, rs, k));}}O2 int Suc(int l, int r,int p,int k) {int &ll = Tr[p].l, &rr = Tr[p].r;if(ll>r||rr<l) {return inf;}if(ll>=l&&rr<=r) {return Trp.Suc(Tr[p].root,k);}else {return min(Suc(l, r, ls, k), Suc(l, r, rs, k));}}O2 int Rank(int l, int r,int p,int k) {int &ll = Tr[p].l, &rr = Tr[p].r;if(ll>r||rr<l) {return 0;}if(ll>=l&&rr<=r) {return Trp.Rank(Tr[p].root,k);}else {return Rank(l, r, ls, k)+Rank(l, r, rs, k);}}O2 int Sum(int l,int r,int k) {int ll = 0, rr = (int) 1e9;while(ll<rr) {int mid = (ll + rr + 1) >> 1;if(Rank(l,r,1,mid)<k) {ll=mid;}else {rr=mid-1;}}return rr;}O2 int query(int l,int r,int p,int x,int y) {if(l>=x&&y>=r) {return Tr[p].minn;}int mid=(l+r)>>1;int rt=0x3f3f3f3f;if(x<=mid) {rt=min(rt,query(l,mid,ls,x,y));}if(y>mid) {rt=min(rt,query(mid+1,r,rs,x,y));}return rt;}
public:O2 void Solve() {Build(1, n, 1);int i,opt,l,r,k,x;for(i=1;i<=m;i++) {opt=Rd.Read();switch (opt) {case 1 : l=Rd.Read(), r=Rd.Read(), k=Rd.Read();printf("%d\n",Rank(l,r,1,k)+1);break;case 2 :l=Rd.Read(), r=Rd.Read(), k=Rd.Read();printf("%d\n",Sum(l,r,k));break;case 3 :k=Rd.Read(), x=Rd.Read();Change(1,k,x);a[k] = x;break;case 4 :l=Rd.Read(), r=Rd.Read(), k=Rd.Read();printf("%d\n", Pre(l, r, 1, k));break;case 5 :l=Rd.Read(), r=Rd.Read(), k=Rd.Read();printf("%d\n", Suc(l, r, 1, k));break;}}}
}Seg;
O2 int main() {srand(20402);n=Rd.Read(),m=Rd.Read();int i;for(i=1;i<=n;i++) a[i]=Rd.Read();Seg.Solve();
}
欢迎来原博客看看 >原文链接<
转载于:https://www.cnblogs.com/Tobichi/p/9107763.html
Bzoj 3196 Tyvj 1730 二逼平衡树相关推荐
- bzoj 3196/tyvj p1730 二逼平衡树
原题链接:http://www.tyvj.cn/p/1730 树套树... 如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #incl ...
- 【BZOJ3196】Tyvj 1730 二逼平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2271 Solved: 935 [Submit][St ...
- 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)
[模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...
- BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)
我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...
- 【BZOJ3196】【Tyvj1730】二逼平衡树,第一次的树套树(线段树+splay)
传送门1 传送门2 写在前面:创造迄今最长的正常代码的记录 思路:个人感觉这个树套树就是对线段树的每个区间建一棵splay来维护,最初觉得这个方法会爆T爆M--(实际上真的可能会爆).对于5个操作,我 ...
- 二逼平衡树——树套树(线段树套Splay平衡树)
题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...
- [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】
题目地址 [洛谷传送门] 题目大意 区间查询k的排名,查找k排名的数,单点修改,区间前驱,区间后继. 感想 真的第一次写树套树,整个人都不对了.重构代码2次,发现样例都过不了,splay直接爆炸,可能 ...
- luogu P3380 【模板】二逼平衡树(树套树)
恭喜你 以分块的姿势通过了此题 #include<cmath> #include<cstdio> #include<algorithm> #define inf ( ...
最新文章
- Java如何优雅的实现时间控制
- 你知道Java内存是怎么管理的么?
- 使用Kettle抽取数据时,出现中文乱码问题解决方案
- 货拉拉携手神策数据,数据赋能企业,实现多元颠覆式创新
- 【Leetcode】二分法左侧边界右侧边界模板
- 【机器学习】与机器学习算法公式相关的数学家,你认识几个?
- LeetCode 874. 模拟行走机器人(set)
- java如何检测输入合法_使用java写的一个简易的计算器,可以检测输入是否合法。.doc...
- tomact配置好ssl证书后访问不到tomact_服务器上配置HTTPS的操作方法!
- Spring AOP(五)之Around增强处理
- 人工智能能为旅游业带来多大的想象空间?
- TCP粘包和拆包问题
- 我是程序员,我在小区“收垃圾”
- App Inventor学习环境搭建
- 微信电话语音质量 VS VOLTE语音质量
- (原创)暴力破解西电校园网密码
- 采购货物和服务的有效步骤
- 【python机器学习基础教程】(四)
- 超宽带(UWB)无线通信技术介绍
- 如何运行从网上下载的iWatch项目详细步骤.
热门文章
- 【计算机组成原理】课本总览
- Windows域策略设置 禁止客户端上网【全域策略生效】
- django进阶07用户模块与权限系统
- python中的return的返回与执行
- 量化策略回测DCCV2
- 怎么做数据可视化大屏?从设计到上线,一般用这3类工具
- python pandas模块_Python3.5 Pandas模块中Series用法详解
- sweetalert2不相应回车_你还不知道的SketchUp建模小技能
- Super Jumping! Jumping! Jumping! 最长上升子序列+DP
- 文件描述符(0、1、2)的用法