[vijos1081]野生动物园(splay)
来源:互联网 发布:centos搭建网站 编辑:程序博客网 时间:2024/04/29 11:25
题目描述
传送门
题解
这道题是主席树裸题啊对不对,为什么要放到平衡树分类里叻?
因为这道题有一个非常特殊的性质:区间不互相包含。
那就是说,如果将区间排序的话,左端点和右端点都是单调的。
那么就可以维护一个平衡树每次查询第k大值就行了,时间复杂度
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 100005#define inf 1000000000int n,m,root,sz;int a[N],f[N],ch[N][2],size[N],key[N],num[N],ans[N];struct hp{int l,r,k,id;}q[N];int cmp(hp a,hp b){ return a.l<b.l||(a.l==b.l&&a.r<b.r);}void clear(int x){ f[x]=ch[x][0]=ch[x][1]=size[x]=key[x]=0;}int get(int x){ return ch[f[x]][1]==x;}void update(int x){ size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}void rotate(int x){ int old=f[x],oldf=f[old],wh=get(x); ch[old][wh]=ch[x][wh^1]; f[ch[old][wh]]=old; ch[x][wh^1]=old; f[old]=x; if (oldf) ch[oldf][ch[oldf][1]==old]=x; f[x]=oldf; update(old); update(x);}void splay(int x){ for (int fa;fa=f[x];rotate(x)) if (f[fa]) rotate( (get(x)==get(fa))?fa:x ); root=x;}void insert(int x){ if (!root) { root=++sz; size[sz]=1; key[sz]=x; return; } int now=root,fa=0; while (1) { fa=now; now=ch[now][x>key[now]]; if (!now) { ++sz; f[sz]=fa;ch[fa][x>key[fa]]=sz; size[sz]=1;key[sz]=x; splay(sz); return; } }}int pre(){ int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now;}void del(int x){ splay(x); if (!ch[root][0]&&!ch[root][1]) { clear(root); root=0; return; } if (!ch[root][0]) { int oldroot=root; root=ch[oldroot][1]; f[root]=0; clear(oldroot); return; } if (!ch[root][1]) { int oldroot=root; root=ch[oldroot][0]; f[root]=0; clear(oldroot); return; } int oldroot=root; int leftbig=pre();splay(leftbig); ch[root][1]=ch[oldroot][1]; f[ch[root][1]]=root; update(root); clear(oldroot); return;}int find(int x){ int now=root; while (1) { if (x<=size[ch[now][0]]) now=ch[now][0]; else { x-=size[ch[now][0]]; if (x==1) return key[now]; --x; now=ch[now][1]; } }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) scanf("%d",&a[i]); for (int i=1;i<=m;++i) scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k),q[i].id=i; sort(q+1,q+m+1,cmp); for (int i=q[1].l;i<=q[1].r;++i) insert(a[i]),num[i]=sz; ans[q[1].id]=find(q[1].k); for (int i=2;i<=m;++i) { for (int j=q[i-1].r+1;j<=q[i].r;++j) insert(a[j]),num[j]=sz; for (int j=q[i-1].l;j<q[i].l;++j) del(num[j]); ans[q[i].id]=find(q[i].k); } for (int i=1;i<=m;++i) printf("%d\n",ans[i]); return 0;}
0 0
- [vijos1081]野生动物园(splay)
- 野生动物园
- 野生动物园的笑话
- 参观了野生动物园
- vijos-P1081 野生动物园
- splay(poj3468)
- Splay树(代码)
- bzoj1208(splay tree)
- Splay POJ3468(老题新做)
- Splay(hdu2475BOX)
- 伸展树(splay)
- [vijos1459]车展(splay)
- 伸展树(Splay)
- 【BZOJ1861】书架(Splay)
- spoj4487(splay)
- luogu2710 数列(splay)
- SPLAY
- splay
- 第十四周11
- spark internal - 作业调度
- 实验 图片查看器
- Token
- MAC版MySQL安装完成后初始密码修改
- [vijos1081]野生动物园(splay)
- apache 日志中记录代理IP以及真实客户端IP
- elf可执行文件的理解(附上elf文件格式图解)
- JDBC的基本操作(CRUD)
- CSS画图形
- (最新教程)基于Windows7+visual Studio2013+Python2.7.12环境下的Caffe配置学习
- 基于ubuntu的Launchpad(5529)开发环境搭建
- 可调参的K-means算法
- printf详细用法