【静态区间K大-权值线段树】POJ 2104 K-th Number
题意:区间K大
代码:
#include<cstdio> #include<algorithm> using namespace std; int n,m,sz,tot; int root[100001],a[100001],ls[8000001],rs[8000001],s[8000001]; int num[100001],hash[100001]; void insert(int l,int r,int x,int &y,int v){ y=++sz; s[y]=s[x]+1; if(l==r)return; ls[y]=ls[x];rs[y]=rs[x]; int mid=(l+r)>>1; if(v<=mid)insert(l,mid,ls[x],ls[y],v); else insert(mid+1,r,rs[x],rs[y],v); } int ask(int l,int r,int x,int y,int k){ if(l==r)return l; int mid=(l+r)>>1; if(s[ls[y]]-s[ls[x]]>=k) return ask(l,mid,ls[x],ls[y],k); else return ask(mid+1,r,rs[x],rs[y],k-(s[ls[y]]-s[ls[x]])); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); num[i]=a[i]; } sort(num+1,num+n+1); hash[++tot]=num[1]; for(int i=2;i<=n;i++) if(num[i]!=num[i-1]) hash[++tot]=num[i]; for(int i=1;i<=n;i++) insert(1,tot,root[i-1],root[i],lower_bound(hash + 1, hash + 1 + tot, a[i]) - hash); for(int i=1;i<=m;i++) { int l,r,x;scanf("%d%d%d",&l,&r,&x); printf("%d\n",hash[ask(1,tot,root[l-1],root[r],x)]); } return 0; }