静态区间第K大

来源:互联网 发布:淘宝开店卖捕鱼游戏币 编辑:程序博客网 时间:2024/04/30 13:59

<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[N],b[N],rank[N],root[N],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;}


0 0
原创粉丝点击