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

9 6
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

2
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 二逼平衡树相关推荐

  1. bzoj 3196/tyvj p1730 二逼平衡树

    原题链接:http://www.tyvj.cn/p/1730 树套树... 如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #incl ...

  2. 【BZOJ3196】Tyvj 1730 二逼平衡树

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...

  3. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2271  Solved: 935 [Submit][St ...

  4. 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)

    [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...

  5. BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)

    我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...

  6. 【BZOJ3196】【Tyvj1730】二逼平衡树,第一次的树套树(线段树+splay)

    传送门1 传送门2 写在前面:创造迄今最长的正常代码的记录 思路:个人感觉这个树套树就是对线段树的每个区间建一棵splay来维护,最初觉得这个方法会爆T爆M--(实际上真的可能会爆).对于5个操作,我 ...

  7. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  8. [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】

    题目地址 [洛谷传送门] 题目大意 区间查询k的排名,查找k排名的数,单点修改,区间前驱,区间后继. 感想 真的第一次写树套树,整个人都不对了.重构代码2次,发现样例都过不了,splay直接爆炸,可能 ...

  9. luogu P3380 【模板】二逼平衡树(树套树)

    恭喜你 以分块的姿势通过了此题 #include<cmath> #include<cstdio> #include<algorithm> #define inf ( ...

最新文章

  1. Java如何优雅的实现时间控制
  2. 你知道Java内存是怎么管理的么?
  3. 使用Kettle抽取数据时,出现中文乱码问题解决方案
  4. 货拉拉携手神策数据,数据赋能企业,实现多元颠覆式创新
  5. 【Leetcode】二分法左侧边界右侧边界模板
  6. 【机器学习】与机器学习算法公式相关的数学家,你认识几个?
  7. LeetCode 874. 模拟行走机器人(set)
  8. java如何检测输入合法_使用java写的一个简易的计算器,可以检测输入是否合法。.doc...
  9. tomact配置好ssl证书后访问不到tomact_服务器上配置HTTPS的操作方法!
  10. Spring AOP(五)之Around增强处理
  11. 人工智能能为旅游业带来多大的想象空间?
  12. TCP粘包和拆包问题
  13. 我是程序员,我在小区“收垃圾”
  14. App Inventor学习环境搭建
  15. 微信电话语音质量 VS VOLTE语音质量
  16. (原创)暴力破解西电校园网密码
  17. 采购货物和服务的有效步骤
  18. 【python机器学习基础教程】(四)
  19. 超宽带(UWB)无线通信技术介绍
  20. 如何运行从网上下载的iWatch项目详细步骤.

热门文章

  1. 【计算机组成原理】课本总览
  2. Windows域策略设置 禁止客户端上网【全域策略生效】
  3. django进阶07用户模块与权限系统
  4. python中的return的返回与执行
  5. 量化策略回测DCCV2
  6. 怎么做数据可视化大屏?从设计到上线,一般用这3类工具
  7. python pandas模块_Python3.5 Pandas模块中Series用法详解
  8. sweetalert2不相应回车_你还不知道的SketchUp建模小技能
  9. Super Jumping! Jumping! Jumping! 最长上升子序列+DP
  10. 文件描述符(0、1、2)的用法