poj2761(treap入门)
2015-10-11 18:13
337 查看
给n个数,然后m个询问,询问任意区间的第k小的数,特别的,任意两个区间不存在包含关系,
也就是说,将所有的询问按L排序之后, 对于i<j , Li < Lj 且 Ri < Rj
所以只要每次查询的时候,treap都是对应区间[Li,Ri] ,那么查找第k小就很简单了
View Code
也就是说,将所有的询问按L排序之后, 对于i<j , Li < Lj 且 Ri < Rj
所以只要每次查询的时候,treap都是对应区间[Li,Ri] ,那么查找第k小就很简单了
#include <iostream> #include <string.h> #include <stdio.h> #include <time.h> #include <algorithm> using namespace std; const int INF = 1<<30; const int N = 100001 + 10; struct Treap { int ch[2]; int fix,key; int same,cnt; }treap[N*40]; struct Node { int l, r,k,id; bool operator<(const Node&rhs)const { return l < rhs.l; } }q[N*5]; int tot; int val ; int ans[N*5]; void maintain(int o) { int lCnt = treap[o].ch[0] == 0 ? 0 : treap[treap[o].ch[0]].cnt; int rCnt = treap[o].ch[1] == 0 ? 0 : treap[treap[o].ch[1]].cnt; treap[o].cnt = treap[o].same + lCnt + rCnt; } void rotate(int &o, int d) { int t = treap[o].ch[d^1]; treap[o].ch[d^1] = treap[t].ch[d]; treap[t].ch[d] = o; maintain(o); maintain(t); o = t; } void insert(int &o, int tkey) { if(o==0) { o = ++tot; if(tot>=N*60) while(true);; treap[o].ch[0] = treap[o].ch[1] = 0; treap[o].cnt = treap[o].same = 1; treap[o].key = tkey; treap[o].fix = rand(); maintain(o); } else if(tkey < treap[o].key) { insert(treap[o].ch[0],tkey); maintain(o); if(treap[treap[o].ch[0]].fix > treap[o].fix) rotate(o,1); } else if(tkey > treap[o].key) { insert(treap[o].ch[1],tkey); maintain(o); if(treap[treap[o].ch[1]].fix > treap[o].fix) rotate(o,0); } else { treap[o].same++; maintain(o); } } void remove(int &o, int tkey) { if(tkey < treap[o].key) { remove(treap[o].ch[0],tkey); } else if(tkey > treap[o].key) { remove(treap[o].ch[1],tkey); } else { if(treap[o].same!=1) treap[o].same--; else if(treap[o].ch[0]==0 && treap[o].ch[1]==0) o = 0; else if(treap[o].ch[0]==0) { rotate(o,0); remove(treap[o].ch[0],tkey); } else if(treap[o].ch[1]==0) { rotate(o,1); remove(treap[o].ch[1],tkey); } else if(treap[treap[o].ch[0]].fix <= treap[treap[o].ch[1]].fix) { rotate(o,0); remove(treap[o].ch[0],tkey); } else { rotate(o,1); remove(treap[o].ch[1],tkey); } } maintain(o); } int query(int o, int k) { while(o) { int cnt = treap[o].ch[0]==0 ? 0 : treap[treap[o].ch[0]].cnt; if(cnt>=k) o = treap[o].ch[0]; else if(cnt<k && k<=cnt+treap[o].same) return treap[o].key; else { k -= cnt + treap[o].same; o = treap[o].ch[1]; } } } int main() { //freopen("d:/in.txt","r",stdin); int n,m; srand(time(0)); while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;++i) { scanf("%d",&val[i]); } tot = 0; for(int i=0;i<m;++i) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k); q[i].id = i; } sort(q,q+m); int root = 0; int L=1,R=1;//初始在Treap中的节点所属区间[L,R),注意半闭半开区间 for(int i=0;i<m;i++) { while(L<q[i].l) { if(L<R) remove(root,val[L]); L++; } if(R<L) R=L; while(R<=q[i].r) { insert(root,val[R]); R++; } ans[q[i].id]=query(root,q[i].k); } for(int i=0;i<m;i++) printf("%d\n",ans[i]); } return 0; }
View Code
相关文章推荐
- 01.移动先行之谁主沉浮----我的第一个程序
- JavaScript基础——类型、值和变量
- 设计模式之责任链模式
- 【转】JAVA的StringBuffer类
- 校门外的树
- English-单词属性缩写
- Android每日范例——TextView文字内容更改
- Python魔法方法指南
- 当使用System,out.println()打印一个对象是自动调用toString方法
- Android每日范例——背景修改
- 汇编语言 第三版 王爽 实验6 更改大写字母
- 02.移动先行之谁主沉浮----第一个通用程序
- service启动和停止,绑定和解除绑定
- 20135308-信息安全系统设计基础第五周学习总结
- cordys BPM 流程设计 常用规范
- WCF跨时区自动转换问题
- O'Reilly
- CocoaPods集成时遇到的问题
- mac QQ 聊天记录 数据表
- java txt 文件的读取 和输出内容