Zoo
来源:互联网 发布:java判断字符串字符集 编辑:程序博客网 时间:2024/04/29 09:11
Description
JZ拥有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强。饲养员西西决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子进行投喂。值得注意的是,西西不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此西西的投喂区间是互不包含的(即区间[1,10]不会与[3,4]或[5,10]同时存在,但可以与[9,11]或[10,20]一起)。同一区间也只会出现一次。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。
Input
觅食能力值。(1<=能力值<=maxlongint)。此后M行,每行描述一次投喂。第t+2的三个数I,J,K表示在第t次投喂中,西西选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。
Output
输出文件有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。插入代码:
Hint
对于100%的数据,有1<=N<=100000,1<=M<=50000。
分析
这题就是要求区间的第k小数。
这也是很经典的主席树。一维维护区间,另一维维护数值的出现次数。
求主席树的过程procedure insert(var x:longint;//注意x是变参,因为每次要改变更新root或lef或rig的值 y,l,r,s:longint);var mid:longint;begin inc(tot); x:=tot; left[x]:=left[y]; right[x]:=right[y];//左右两边复制 sum[x]:=sum[y]+1;//更新,统计 mid:=(l+r)shr 1; if l=r then exit; if mid>=s then insert(left[x],left[y],l,mid,s) else insert(right[x],right[y],mid+1,r,s);//修改其他部分end;
查询代码(第k小)
function query(l,r,x,y,z:longint):longint;var mid:longint;begin if l=r then exit(l); mid:=(l+r)shr 1; if sum[left[y]]-sum[left[x]]>=z then exit(query(l,mid,left[x],left[y],z)) else exit(query(mid+1,r,right[x],right[y],z-sum[left[y]]+sum[left[x]]));//通过计算区间里面的数的个数来判断这个数在左边还是右边end;
其实很类似线段树。
代码
var a,b,c,d:array[0..1000000] of longint; tot,i,n,m,lf,rf,vf,t:longint; left,right,sum,root:array[0..15000000] of longint;procedure qrt(l,r:longint);var i,j,mid:longint;begin i:=l;j:=r;mid:=a[(l+r)shr 1]; repeat while a[i]<mid do inc(i); while a[j]>mid do dec(j); if i<=j then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];inc(i);dec(j); end; until i>j; if l<j then qrt(l,j); if i<r then qrt(i,r);end;procedure insert(var x:longint;y,l,r,s:longint);var mid:longint;begin inc(tot); x:=tot; left[x]:=left[y]; right[x]:=right[y]; sum[x]:=sum[y]+1; mid:=(l+r)shr 1; if l=r then exit; if mid>=s then insert(left[x],left[y],l,mid,s) else insert(right[x],right[y],mid+1,r,s);end;function query(l,r,x,y,z:longint):longint;var mid:longint;begin if l=r then exit(l); mid:=(l+r)shr 1; if sum[left[y]]-sum[left[x]]>=z then exit(query(l,mid,left[x],left[y],z)) else exit(query(mid+1,r,right[x],right[y],z-sum[left[y]]+sum[left[x]]));end;begin readln(n,m); for i:=1 to n do begin read(a[i]); b[i]:=i; end; qrt(1,n);a[0]:=0; for i:=1 to n do if a[i]<>a[i-1] then begin inc(t); c[i]:=t; d[t]:=a[i]; end else c[i]:=t; for i:=1 to n do a[b[i]]:=c[i]; for i:=1 to n do insert(root[i],root[i-1],1,t,a[i]); for i:=1 to m do begin readln(lf,rf,vf); writeln(d[query(1,t,root[lf-1],root[rf],vf)]); end;close(input);close(output);end.
1 0
- Zoo
- ZOO
- APIO07-zoo
- NOI ZOO
- 【Zookeeper】zoo.cfg 说明
- [Apio2007]Zoo解题报告
- codeforces 183B - Zoo
- Caffe Model Zoo
- 困兽.Zoo
- 1002 Caffe Model Zoo
- Caffe Model Zoo
- bzoj1151: [CTSC2007]动物园zoo
- caffe:Model-Zoo
- zookeeper配制zoo.cfg
- [CTSC2007]动物园zoo
- 【Zookeeper】zoo.cfg 说明
- 支持zoo in, zoo out的TouchImageViewActivity组件
- cf437D The Child and Zoo
- Genymotion - 强大好用高性能的 Android 模拟器 (在电脑流畅运行APK安卓软件游戏的利器)
- Android 中dp,px,dpi以及sp的区别
- 网络中一些特殊的地址和地址范围
- 安卓开发-Activity中finish() onDestroy() 和System.exit()的区别
- 给文本文件加密解密
- Zoo
- pow函数
- 查看MYSQL数据库中所有用户及拥有权限
- 修改终端下vim的PopupMenu选种项的背景颜色
- python小记-一款不错的编译器
- Java程序员在用的大数据工具
- 微软Remote Modern IE 访问
- HDU-ACM-2016
- Android Studio 提高代码质量——Inspact Code