您的位置:首页 > 其它

静态区间第K大

2015-12-08 20:39 190 查看
<a target=_blank href="http://poj.org/problem?id=2104" target="_blank"><span style="font-size:24px;">POJ 2104</span></a>

POJ 2761

做法好多,主席树,划分树,离线处理(曼哈顿最小生成树?)+BST(Treap or Splay or SBT),貌似分治+BIT也可以,不过懒得搞了。

以后复习模板时用得上。

主席树:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
struct Node{
int l,r,w;
}tr[N*20];
int a
,b
,rank
,root
,sz;
void ins(int &i,int l,int r,int x){
tr[++sz]=tr[i];i=sz;
tr[i].w++;
if(l==r)return;
int m=l+r>>1;
if(x<=m)ins(tr[i].l,l,m,x);
else ins(tr[i].r,m+1,r,x);
}
int query(int i,int j,int l,int r,int k){
if(l==r)return l;
int m=l+r>>1;
int tmp=tr[tr[j].l].w-tr[tr[i].l].w;
if(k<=tmp)return query(tr[i].l,tr[j].l,l,m,k);
else  return query(tr[i].r,tr[j].r,m+1,r,k-tmp);
}
inline bool cmp(int i,int j){
return a[i]<a[j];
}
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);rank[i]=i;
}
sort(rank+1,rank+1+n,cmp);
for(int i=1;i<=n;i++)b[rank[i]]=i;
for(int i=1;i<=n;i++){
root[i]=root[i-1];
ins(root[i],1,n,b[i]);
}
int x,y,k;
while(m--){
scanf("%d%d%d",&x,&y,&k);
int tmp=query(root[x-1],root[y],1,n,k);
printf("%d\n",a[rank[tmp]]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: