poj 2761 feeding the dog (splay树 模板)
来源:互联网 发布:ecshop源码下载 编辑:程序博客网 时间:2024/04/30 12:10
题意:
给你N个数,然后要你对下面M个查询回答:(L,R,K)。回答第L个数到第R个数之间的第K小数的值是多少。其中任意给定的两个区间[Li,Ri]和[Lj,Rj]之间不存在包含关系。
splay模板题,果然不是自己写的模板就是很多不了解的地方,调试起来贼鸡巴麻烦。
所有的真正的东西都存在结构体里面,查询返回的是离散化后的树上的节点次序。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cstdlib>#include <cmath>#include <utility>#include <vector>#include <queue>#include <map>#include <set>#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define INF 0x3f3f3f3f#define MAXN 100005using namespace std;int cnt,rt;void init(){ cnt=1,rt=0;}int id[MAXN],res[MAXN];struct node{ int l,r,k; int id;}s[MAXN];struct Tree{ int key,size,fa,son[2],num; void set(int _key,int _size,int _fa,int _num) { key=_key; size=_size; fa=_fa; son[0]=son[1]=0; num=_num; }}T[MAXN];int cmp(node a,node b){ if(a.l==b.l) return a.r>b.r; else return a.l<b.l; } inline void PushUp(int x){ T[x].size=T[T[x].son[0]].size+T[T[x].son[1]].size+1;}inline void Rotate(int x,int p){ int y=T[x].fa; T[y].son[!p]=T[x].son[p]; T[T[x].son[p]].fa=y; T[x].fa=T[y].fa; if(T[x].fa) T[T[x].fa].son[T[T[x].fa].son[1]==y]=x; T[x].son[p]=y; T[y].fa=x; PushUp(y); PushUp(x);}void Splay(int x,int To){ while(T[x].fa!=To) //直到父节点为To { if(T[T[x].fa].fa==To) //如果父节点的父节点==To 单旋 Rotate(x,T[T[x].fa].son[0]==x); else //如果的父节点的父节点!=to 双旋 { int y=T[x].fa,z=T[y].fa; //y是父节点,z是父节点的父节点 int p=(T[z].son[0]==y);//y是不是在父节点的0路线 if(T[y].son[p]==x) //这里判断是不是和父节点所在路线相反 Rotate(x,!p),Rotate(x,p);// 如果相反 就是之字形 else Rotate(y,p),Rotate(x,p);//相同 一字型 } } if(To==0) rt=x;}void Insert(int key,int num)//插入key 并且将该节点转移到根处{ if(!rt) T[rt=cnt++].set(key,1,0,num); else { int x=rt,y=0; while(x) { y=x; x=T[x].son[key>T[x].key]; } T[x = cnt++].set(key,1,y,num); T[y].son[key>T[y].key]=x; Splay(x,0); }}int find(int key){ int x=rt; while(x&&T[x].key!=key) x=T[x].son[key>T[x].key]; if(x) Splay(x,0); return x;}int GetPth(int p) //获得第p小的节点 并将其转移到根处{ if(!rt) return 0; int x=rt,ret=0; while(x) { if(p==T[T[x].son[0]].size+1) break; if(p>T[T[x].son[0]].size+1) //判断是第p个是在左边还是右边 { p-=T[T[x].son[0]].size+1; x=T[x].son[1]; } else x=T[x].son[0]; } Splay(x,0); return x;}void Delete(int key)//删除值为key的节点 若有重点只删其中一个 x的前驱移动到根处{ int x=find(key); //找到与key值相同的 if(!x) return ; //如果没有就return int y=T[x].son[0]; while(T[y].son[1]) //找到左边叶子结点 y=T[y].son[1]; int z=T[x].son[1]; //找到右边叶子结点 while(T[z].son[0]) z=T[z].son[0]; if(!y&&!z) //如果这是根结点 { rt=0; return ; } if(!y) //只有右叶子结点 { Splay(z,0); T[z].son[0]=0; PushUp(z); return ; } if(!z) //只有左叶子结点 { Splay(y,0); T[y].son[1]=0; PushUp(y); return ; } Splay(y,0); Splay(z,y); T[z].son[0]=0; PushUp(z); PushUp(y);}int main (){ int n,m; while(scanf("%d%d", &n,&m)!=EOF) { init(); for(int i=1;i<=n;i++) scanf("%d",&id[i]); for(int i=0;i<m;i++) { scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].k); s[i].id=i; } sort(s,s+m,cmp); for(int i=s[0].l;i<=s[0].r;i++) Insert(id[i],0); //插入需要保留的值。第一个是优先级 //但是在插入后它会进行离散化。这个值会保存在结构体里面 res[s[0].id]=T[GetPth(s[0].k)].key;//由于有离散化 所以返回的是第k个节点 //通过结构体转回值 for(int i=1;i<m;i++) { for(int j=s[i-1].l;j<s[i].l;j++) Delete(id[j]);//删除的是具体值,然后它会找在第几个节点上 if(s[i].r<s[i-1].r) { for(int j=s[i].r+1;j<=s[i-1].r;j++) Delete(id[j]); } if(s[i].r>s[i-1].r) { for(int j=s[i-1].r+1;j<=s[i].r;j++) { Insert(id[j],0); } } res[s[i].id]=T[GetPth(s[i].k)].key;//由于有离散化 所以返回的是第k个节点 //通过结构体转回值 } for(int i=0;i<m;i++) printf("%d\n",res[i]); } return 0;}
0 0
- poj 2761 feeding the dog (splay树 模板)
- poj 3481 double Queue(Splay树 模板解读)
- poj 3580 SuperMemo splay树模板题
- POJ 1034 The Dog Task
- poj 1034 The dog task
- poj 1034 The dog task
- poj 1034 The dog task
- Splay树(区间第k小)——POJ 2761 Feed the dogs
- POJ 3580 SuperMemo(Splay模板)
- POJ 3580 splay模板题
- poj 1442 splay 模板题
- POJ-3481 Double Queue (平衡树 入门题 splay模板题)
- POJ 1034 The dog task 笔记
- 【bzoj3224】平衡树模板(Splay)
- 【模板】普通平衡树(splay)
- 【模板】文艺平衡树(Splay)
- P3391 【模板】文艺平衡树(Splay)
- Splay伸展树&模板
- 前端实时搜索功能
- 重修大学JAVA课--应用类型比较器的实现方法
- HTML中属性id和属性name有何区别?
- CMD查看本机IP
- word-ladder
- poj 2761 feeding the dog (splay树 模板)
- Abaqus建模受力分析
- java I/O流(一)——FileWriter,BufferedWriter,inputStream,BufferedInputStream,InputStreamReader
- linux中math.h库的使用
- zstack(0)前言
- 多项式求和
- 示例:在约会网站上使用k-近邻算法
- Arcgis开发各种记录。。
- Why Apache Flink®?